Update app.py
Browse files
app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
"""
|
| 2 |
๐ ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION
|
| 3 |
With Audit Trail, Incident History, Memory Graph, and Enterprise Features
|
|
|
|
| 4 |
"""
|
| 5 |
|
| 6 |
import logging
|
|
@@ -346,7 +347,7 @@ class AuditTrailManager:
|
|
| 346 |
}, indent=2, default=str)
|
| 347 |
|
| 348 |
# ===========================================
|
| 349 |
-
# ENHANCED VISUALIZATION ENGINE
|
| 350 |
# ===========================================
|
| 351 |
|
| 352 |
class EnhancedVisualizationEngine:
|
|
@@ -375,40 +376,67 @@ class EnhancedVisualizationEngine:
|
|
| 375 |
"stable": "darkgreen"
|
| 376 |
}
|
| 377 |
|
| 378 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
fig.add_trace(go.Scatter(
|
| 380 |
-
x=[
|
| 381 |
-
y=[1],
|
| 382 |
-
mode='
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
symbol='circle' if event["type"] in ['problem', 'alert'] else 'diamond',
|
| 387 |
-
line=dict(width=2, color='white')
|
| 388 |
-
),
|
| 389 |
-
text=[event["event"]],
|
| 390 |
-
textposition="top center",
|
| 391 |
-
name=event["type"].capitalize(),
|
| 392 |
-
hovertemplate="<b>%{text}</b><br>%{x|%H:%M:%S}<extra></extra>"
|
| 393 |
))
|
| 394 |
|
| 395 |
fig.update_layout(
|
| 396 |
title="<b>Incident Timeline - Cache Miss Storm Resolution</b>",
|
| 397 |
xaxis_title="Time โ",
|
| 398 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 399 |
height=450,
|
| 400 |
-
showlegend=
|
| 401 |
-
paper_bgcolor='
|
| 402 |
-
plot_bgcolor='
|
| 403 |
hovermode='closest',
|
| 404 |
xaxis=dict(
|
| 405 |
tickformat='%H:%M',
|
| 406 |
-
gridcolor='rgba(200,200,200,0.2)'
|
|
|
|
| 407 |
),
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
gridcolor='rgba(200,200,200,0.1)'
|
| 411 |
-
)
|
| 412 |
)
|
| 413 |
|
| 414 |
return fig
|
|
@@ -510,12 +538,21 @@ class EnhancedVisualizationEngine:
|
|
| 510 |
fig.update_layout(
|
| 511 |
height=700,
|
| 512 |
showlegend=True,
|
| 513 |
-
paper_bgcolor='
|
| 514 |
-
plot_bgcolor='
|
| 515 |
title_text="<b>Executive Business Dashboard</b>",
|
| 516 |
-
barmode='group'
|
|
|
|
| 517 |
)
|
| 518 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 519 |
return fig
|
| 520 |
|
| 521 |
@staticmethod
|
|
@@ -526,10 +563,12 @@ class EnhancedVisualizationEngine:
|
|
| 526 |
if not executions:
|
| 527 |
fig = go.Figure()
|
| 528 |
fig.update_layout(
|
| 529 |
-
title="No execution history yet",
|
| 530 |
height=400,
|
| 531 |
-
paper_bgcolor='
|
| 532 |
-
plot_bgcolor='
|
|
|
|
|
|
|
| 533 |
)
|
| 534 |
return fig
|
| 535 |
|
|
@@ -559,11 +598,18 @@ class EnhancedVisualizationEngine:
|
|
| 559 |
xaxis_title="Scenario",
|
| 560 |
yaxis_title="Cost Saved ($)",
|
| 561 |
height=500,
|
| 562 |
-
paper_bgcolor='
|
| 563 |
-
plot_bgcolor='
|
| 564 |
-
showlegend=False
|
|
|
|
|
|
|
|
|
|
| 565 |
)
|
| 566 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 567 |
return fig
|
| 568 |
|
| 569 |
@staticmethod
|
|
@@ -576,43 +622,63 @@ class EnhancedVisualizationEngine:
|
|
| 576 |
incidents = list(audit_manager.incident_history)[:20] # Last 20 incidents
|
| 577 |
|
| 578 |
if not incidents:
|
| 579 |
-
# Create
|
| 580 |
-
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 586 |
|
| 587 |
-
|
| 588 |
-
|
| 589 |
-
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
edges = []
|
| 596 |
|
| 597 |
-
|
| 598 |
-
|
| 599 |
-
|
| 600 |
-
|
| 601 |
-
|
| 602 |
-
|
| 603 |
-
|
| 604 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 605 |
})
|
| 606 |
-
|
| 607 |
-
# Create edges to previous incidents
|
| 608 |
-
if i > 0:
|
| 609 |
-
prev_id = f"Incident_{i-1}"
|
| 610 |
-
edges.append({
|
| 611 |
-
"source": prev_id,
|
| 612 |
-
"target": node_id,
|
| 613 |
-
"weight": 0.7,
|
| 614 |
-
"label": "related_to"
|
| 615 |
-
})
|
| 616 |
|
| 617 |
# Color mapping
|
| 618 |
color_map = {
|
|
@@ -622,70 +688,73 @@ class EnhancedVisualizationEngine:
|
|
| 622 |
"component": "#96CEB4"
|
| 623 |
}
|
| 624 |
|
| 625 |
-
#
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
node_color = []
|
| 630 |
-
node_size = []
|
| 631 |
-
|
| 632 |
-
for i, node in enumerate(nodes):
|
| 633 |
-
# Simple layout - could be enhanced with networkx
|
| 634 |
-
angle = 2 * np.pi * i / len(nodes)
|
| 635 |
radius = 1.0
|
|
|
|
|
|
|
| 636 |
|
| 637 |
-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
| 657 |
-
|
| 658 |
-
|
| 659 |
-
|
| 660 |
-
|
| 661 |
-
|
| 662 |
-
|
| 663 |
-
|
| 664 |
-
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
))
|
| 676 |
-
except StopIteration:
|
| 677 |
-
continue
|
| 678 |
|
| 679 |
fig.update_layout(
|
| 680 |
-
title="<b>Incident Memory Graph</b>",
|
| 681 |
-
showlegend=
|
| 682 |
height=600,
|
| 683 |
-
paper_bgcolor='
|
| 684 |
-
plot_bgcolor='
|
| 685 |
hovermode='closest',
|
| 686 |
-
xaxis=dict(
|
| 687 |
-
|
| 688 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 689 |
)
|
| 690 |
|
| 691 |
return fig
|
|
@@ -697,7 +766,8 @@ class EnhancedVisualizationEngine:
|
|
| 697 |
rows=2, cols=2,
|
| 698 |
subplot_titles=('Incident Frequency', 'Resolution Times',
|
| 699 |
'Success Rates', 'Pattern Correlation'),
|
| 700 |
-
vertical_spacing=0.15
|
|
|
|
| 701 |
)
|
| 702 |
|
| 703 |
# Sample data - in real app this would come from analysis
|
|
@@ -708,19 +778,34 @@ class EnhancedVisualizationEngine:
|
|
| 708 |
|
| 709 |
# Incident Frequency
|
| 710 |
fig.add_trace(
|
| 711 |
-
go.Bar(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 712 |
row=1, col=1
|
| 713 |
)
|
| 714 |
|
| 715 |
# Resolution Times
|
| 716 |
fig.add_trace(
|
| 717 |
-
go.Bar(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 718 |
row=1, col=2
|
| 719 |
)
|
| 720 |
|
| 721 |
# Success Rates
|
| 722 |
fig.add_trace(
|
| 723 |
-
go.Bar(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 724 |
row=2, col=1
|
| 725 |
)
|
| 726 |
|
|
@@ -734,16 +819,32 @@ class EnhancedVisualizationEngine:
|
|
| 734 |
])
|
| 735 |
|
| 736 |
fig.add_trace(
|
| 737 |
-
go.Heatmap(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 738 |
row=2, col=2
|
| 739 |
)
|
| 740 |
|
| 741 |
fig.update_layout(
|
| 742 |
height=700,
|
| 743 |
showlegend=False,
|
| 744 |
-
title_text="<b>Pattern Analysis Dashboard</b>"
|
|
|
|
|
|
|
| 745 |
)
|
| 746 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 747 |
return fig
|
| 748 |
|
| 749 |
# ===========================================
|
|
@@ -1106,7 +1207,7 @@ class EnhancedBusinessLogic:
|
|
| 1106 |
return temp_file.name
|
| 1107 |
|
| 1108 |
# ===========================================
|
| 1109 |
-
# MAIN INTERFACE
|
| 1110 |
# ===========================================
|
| 1111 |
|
| 1112 |
def create_interface() -> gr.Blocks:
|
|
@@ -1122,11 +1223,12 @@ def create_interface() -> gr.Blocks:
|
|
| 1122 |
h1, h2, h3 { color: #1a365d !important; }
|
| 1123 |
.critical { color: #FF6B6B !important; font-weight: bold; }
|
| 1124 |
.success { color: #4ECDC4 !important; font-weight: bold; }
|
|
|
|
| 1125 |
"""
|
| 1126 |
|
| 1127 |
with gr.Blocks(
|
| 1128 |
title="๐ ARF Investor Demo v3.8.0",
|
| 1129 |
-
theme=gr.themes.Soft(),
|
| 1130 |
css=custom_css
|
| 1131 |
) as demo:
|
| 1132 |
|
|
@@ -1178,7 +1280,10 @@ def create_interface() -> gr.Blocks:
|
|
| 1178 |
with gr.Column(scale=2):
|
| 1179 |
# Visualization
|
| 1180 |
gr.Markdown("### ๐ Incident Timeline")
|
| 1181 |
-
timeline_output = gr.Plot(
|
|
|
|
|
|
|
|
|
|
| 1182 |
|
| 1183 |
# Action Section
|
| 1184 |
gr.Markdown("### โก Take Action")
|
|
@@ -1217,7 +1322,10 @@ def create_interface() -> gr.Blocks:
|
|
| 1217 |
with gr.Column():
|
| 1218 |
# Business Dashboard
|
| 1219 |
gr.Markdown("### ๐ Executive Business Dashboard")
|
| 1220 |
-
dashboard_output = gr.Plot(
|
|
|
|
|
|
|
|
|
|
| 1221 |
|
| 1222 |
# ROI Calculator
|
| 1223 |
gr.Markdown("### ๐งฎ Interactive ROI Calculator")
|
|
@@ -1289,7 +1397,10 @@ def create_interface() -> gr.Blocks:
|
|
| 1289 |
)
|
| 1290 |
|
| 1291 |
gr.Markdown("### ๐ Visual History")
|
| 1292 |
-
execution_chart = gr.Plot(
|
|
|
|
|
|
|
|
|
|
| 1293 |
|
| 1294 |
# AI Analysis Results
|
| 1295 |
gr.Markdown("### ๐ง AI Pattern Analysis")
|
|
@@ -1312,7 +1423,10 @@ def create_interface() -> gr.Blocks:
|
|
| 1312 |
|
| 1313 |
# Memory Graph Visualization
|
| 1314 |
gr.Markdown("### ๐ง Memory Graph")
|
| 1315 |
-
memory_graph = gr.Plot(
|
|
|
|
|
|
|
|
|
|
| 1316 |
|
| 1317 |
# Export Area
|
| 1318 |
gr.Markdown("### ๐ค Export & Analytics")
|
|
@@ -1444,7 +1558,10 @@ def create_interface() -> gr.Blocks:
|
|
| 1444 |
auto_layout = gr.Checkbox(label="Auto-Layout", value=True)
|
| 1445 |
|
| 1446 |
# Graph Visualization
|
| 1447 |
-
memory_graph_plot = gr.Plot(
|
|
|
|
|
|
|
|
|
|
| 1448 |
|
| 1449 |
# Node Details
|
| 1450 |
gr.Markdown("### ๐ Selected Node Details")
|
|
@@ -1711,12 +1828,24 @@ def create_interface() -> gr.Blocks:
|
|
| 1711 |
auto_layout=auto_layout
|
| 1712 |
)
|
| 1713 |
|
| 1714 |
-
|
| 1715 |
-
|
| 1716 |
-
|
| 1717 |
-
|
| 1718 |
-
|
| 1719 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1720 |
|
| 1721 |
def search_memory(query: str) -> Tuple[List[List[str]], str]:
|
| 1722 |
"""Search memory"""
|
|
@@ -1762,9 +1891,10 @@ def create_interface() -> gr.Blocks:
|
|
| 1762 |
)
|
| 1763 |
|
| 1764 |
# ===========================================
|
| 1765 |
-
# INITIALIZATION
|
| 1766 |
# ===========================================
|
| 1767 |
|
|
|
|
| 1768 |
demo.load(
|
| 1769 |
fn=lambda: (
|
| 1770 |
viz_engine.create_business_dashboard(),
|
|
|
|
| 1 |
"""
|
| 2 |
๐ ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION
|
| 3 |
With Audit Trail, Incident History, Memory Graph, and Enterprise Features
|
| 4 |
+
FIXED VERSION - No Plot Errors
|
| 5 |
"""
|
| 6 |
|
| 7 |
import logging
|
|
|
|
| 347 |
}, indent=2, default=str)
|
| 348 |
|
| 349 |
# ===========================================
|
| 350 |
+
# ENHANCED VISUALIZATION ENGINE (FIXED)
|
| 351 |
# ===========================================
|
| 352 |
|
| 353 |
class EnhancedVisualizationEngine:
|
|
|
|
| 376 |
"stable": "darkgreen"
|
| 377 |
}
|
| 378 |
|
| 379 |
+
symbol_map = {
|
| 380 |
+
"problem": "circle", "alert": "circle", "detection": "diamond",
|
| 381 |
+
"analysis": "diamond", "action": "square", "recovery": "star",
|
| 382 |
+
"stable": "cross"
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
# Convert datetime objects to strings for Plotly
|
| 386 |
+
times = [event["time"] for event in events]
|
| 387 |
+
events_text = [event["event"] for event in events]
|
| 388 |
+
event_types = [event["type"] for event in events]
|
| 389 |
+
colors = [color_map[event_type] for event_type in event_types]
|
| 390 |
+
symbols = [symbol_map[event_type] for event_type in event_types]
|
| 391 |
+
|
| 392 |
+
fig.add_trace(go.Scatter(
|
| 393 |
+
x=times,
|
| 394 |
+
y=[1] * len(events), # Fixed y-position
|
| 395 |
+
mode='markers+text',
|
| 396 |
+
marker=dict(
|
| 397 |
+
size=20,
|
| 398 |
+
color=colors,
|
| 399 |
+
symbol=symbols,
|
| 400 |
+
line=dict(width=2, color='white')
|
| 401 |
+
),
|
| 402 |
+
text=events_text,
|
| 403 |
+
textposition="top center",
|
| 404 |
+
hoverinfo="text",
|
| 405 |
+
hovertemplate="<b>%{text}</b><br>%{x|%H:%M:%S}<extra></extra>",
|
| 406 |
+
name="Timeline Events"
|
| 407 |
+
))
|
| 408 |
+
|
| 409 |
+
# Add connecting lines
|
| 410 |
+
for i in range(len(times) - 1):
|
| 411 |
fig.add_trace(go.Scatter(
|
| 412 |
+
x=[times[i], times[i + 1]],
|
| 413 |
+
y=[1, 1],
|
| 414 |
+
mode='lines',
|
| 415 |
+
line=dict(color='gray', width=1, dash='dash'),
|
| 416 |
+
showlegend=False,
|
| 417 |
+
hoverinfo='none'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 418 |
))
|
| 419 |
|
| 420 |
fig.update_layout(
|
| 421 |
title="<b>Incident Timeline - Cache Miss Storm Resolution</b>",
|
| 422 |
xaxis_title="Time โ",
|
| 423 |
+
yaxis=dict(
|
| 424 |
+
title="Event Type",
|
| 425 |
+
showticklabels=False,
|
| 426 |
+
range=[0.5, 1.5] # Fixed range for better display
|
| 427 |
+
),
|
| 428 |
height=450,
|
| 429 |
+
showlegend=False,
|
| 430 |
+
paper_bgcolor='white',
|
| 431 |
+
plot_bgcolor='white',
|
| 432 |
hovermode='closest',
|
| 433 |
xaxis=dict(
|
| 434 |
tickformat='%H:%M',
|
| 435 |
+
gridcolor='rgba(200,200,200,0.2)',
|
| 436 |
+
showgrid=True
|
| 437 |
),
|
| 438 |
+
yaxis_showgrid=False,
|
| 439 |
+
margin=dict(l=50, r=50, t=80, b=50)
|
|
|
|
|
|
|
| 440 |
)
|
| 441 |
|
| 442 |
return fig
|
|
|
|
| 538 |
fig.update_layout(
|
| 539 |
height=700,
|
| 540 |
showlegend=True,
|
| 541 |
+
paper_bgcolor='white',
|
| 542 |
+
plot_bgcolor='white',
|
| 543 |
title_text="<b>Executive Business Dashboard</b>",
|
| 544 |
+
barmode='group',
|
| 545 |
+
margin=dict(l=50, r=50, t=100, b=50)
|
| 546 |
)
|
| 547 |
|
| 548 |
+
# Update axes
|
| 549 |
+
fig.update_xaxes(title_text="Scenario", row=1, col=1)
|
| 550 |
+
fig.update_yaxes(title_text="Cost ($)", row=1, col=1)
|
| 551 |
+
fig.update_xaxes(title_text="Activity", row=1, col=2)
|
| 552 |
+
fig.update_yaxes(title_text="Percentage (%)", row=1, col=2)
|
| 553 |
+
fig.update_xaxes(title_text="Approach", row=2, col=1)
|
| 554 |
+
fig.update_yaxes(title_text="MTTR (minutes)", row=2, col=1)
|
| 555 |
+
|
| 556 |
return fig
|
| 557 |
|
| 558 |
@staticmethod
|
|
|
|
| 563 |
if not executions:
|
| 564 |
fig = go.Figure()
|
| 565 |
fig.update_layout(
|
| 566 |
+
title="<b>No execution history yet</b>",
|
| 567 |
height=400,
|
| 568 |
+
paper_bgcolor='white',
|
| 569 |
+
plot_bgcolor='white',
|
| 570 |
+
xaxis_showgrid=True,
|
| 571 |
+
yaxis_showgrid=True
|
| 572 |
)
|
| 573 |
return fig
|
| 574 |
|
|
|
|
| 598 |
xaxis_title="Scenario",
|
| 599 |
yaxis_title="Cost Saved ($)",
|
| 600 |
height=500,
|
| 601 |
+
paper_bgcolor='white',
|
| 602 |
+
plot_bgcolor='white',
|
| 603 |
+
showlegend=False,
|
| 604 |
+
xaxis_showgrid=True,
|
| 605 |
+
yaxis_showgrid=True,
|
| 606 |
+
margin=dict(l=50, r=50, t=80, b=100)
|
| 607 |
)
|
| 608 |
|
| 609 |
+
# Rotate x-axis labels if needed
|
| 610 |
+
if len(scenarios) > 5:
|
| 611 |
+
fig.update_xaxes(tickangle=45)
|
| 612 |
+
|
| 613 |
return fig
|
| 614 |
|
| 615 |
@staticmethod
|
|
|
|
| 622 |
incidents = list(audit_manager.incident_history)[:20] # Last 20 incidents
|
| 623 |
|
| 624 |
if not incidents:
|
| 625 |
+
# Create a simple placeholder graph
|
| 626 |
+
fig.add_trace(go.Scatter(
|
| 627 |
+
x=[0, 1, 0.5],
|
| 628 |
+
y=[0, 0, 0.866],
|
| 629 |
+
mode='markers+text',
|
| 630 |
+
marker=dict(
|
| 631 |
+
size=[30, 20, 20],
|
| 632 |
+
color=['#FF6B6B', '#4ECDC4', '#45B7D1']
|
| 633 |
+
),
|
| 634 |
+
text=['Incident', 'Action', 'Outcome'],
|
| 635 |
+
textposition="top center"
|
| 636 |
+
))
|
| 637 |
|
| 638 |
+
# Add edges
|
| 639 |
+
fig.add_trace(go.Scatter(
|
| 640 |
+
x=[0, 0.5, 1],
|
| 641 |
+
y=[0, 0.866, 0],
|
| 642 |
+
mode='lines',
|
| 643 |
+
line=dict(color='gray', width=2),
|
| 644 |
+
hoverinfo='none'
|
| 645 |
+
))
|
|
|
|
| 646 |
|
| 647 |
+
fig.update_layout(
|
| 648 |
+
title="<b>Incident Memory Graph (Sample)</b>",
|
| 649 |
+
showlegend=False,
|
| 650 |
+
height=600,
|
| 651 |
+
paper_bgcolor='white',
|
| 652 |
+
plot_bgcolor='white',
|
| 653 |
+
xaxis=dict(showgrid=False, zeroline=False, showticklabels=False, range=[-0.2, 1.2]),
|
| 654 |
+
yaxis=dict(showgrid=False, zeroline=False, showticklabels=False, range=[-0.2, 1.2]),
|
| 655 |
+
margin=dict(l=20, r=20, t=60, b=20)
|
| 656 |
+
)
|
| 657 |
+
return fig
|
| 658 |
+
|
| 659 |
+
# Create nodes from actual incidents
|
| 660 |
+
nodes = []
|
| 661 |
+
edges = []
|
| 662 |
+
|
| 663 |
+
for i, incident in enumerate(incidents):
|
| 664 |
+
node_id = f"Incident_{i}"
|
| 665 |
+
nodes.append({
|
| 666 |
+
"id": node_id,
|
| 667 |
+
"label": incident["type"][:20],
|
| 668 |
+
"type": "incident",
|
| 669 |
+
"size": 15 + (incident.get("severity", 2) * 5),
|
| 670 |
+
"severity": incident.get("severity", 2)
|
| 671 |
+
})
|
| 672 |
+
|
| 673 |
+
# Create edges to previous incidents
|
| 674 |
+
if i > 0 and i % 3 == 0: # Connect every 3rd incident
|
| 675 |
+
prev_id = f"Incident_{i-1}"
|
| 676 |
+
edges.append({
|
| 677 |
+
"source": prev_id,
|
| 678 |
+
"target": node_id,
|
| 679 |
+
"weight": 0.7,
|
| 680 |
+
"label": "related_to"
|
| 681 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 682 |
|
| 683 |
# Color mapping
|
| 684 |
color_map = {
|
|
|
|
| 688 |
"component": "#96CEB4"
|
| 689 |
}
|
| 690 |
|
| 691 |
+
# Calculate positions (circular layout)
|
| 692 |
+
num_nodes = len(nodes)
|
| 693 |
+
if num_nodes > 0:
|
| 694 |
+
angles = np.linspace(0, 2 * np.pi, num_nodes, endpoint=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 695 |
radius = 1.0
|
| 696 |
+
node_x = radius * np.cos(angles)
|
| 697 |
+
node_y = radius * np.sin(angles)
|
| 698 |
|
| 699 |
+
# Add nodes
|
| 700 |
+
fig.add_trace(go.Scatter(
|
| 701 |
+
x=node_x,
|
| 702 |
+
y=node_y,
|
| 703 |
+
mode='markers+text',
|
| 704 |
+
marker=dict(
|
| 705 |
+
size=[node.get("size", 15) for node in nodes],
|
| 706 |
+
color=[color_map.get(node.get("type", "incident"), "#999999") for node in nodes],
|
| 707 |
+
line=dict(width=2, color='white')
|
| 708 |
+
),
|
| 709 |
+
text=[node["label"] for node in nodes],
|
| 710 |
+
textposition="top center",
|
| 711 |
+
hovertext=[f"Type: {node['type']}<br>Severity: {node.get('severity', 'N/A')}" for node in nodes],
|
| 712 |
+
hoverinfo="text",
|
| 713 |
+
name="Nodes"
|
| 714 |
+
))
|
| 715 |
+
|
| 716 |
+
# Add edges if we have them
|
| 717 |
+
if edges:
|
| 718 |
+
for edge in edges:
|
| 719 |
+
try:
|
| 720 |
+
source_idx = int(edge["source"].split("_")[1])
|
| 721 |
+
target_idx = int(edge["target"].split("_")[1])
|
| 722 |
+
|
| 723 |
+
if source_idx < num_nodes and target_idx < num_nodes:
|
| 724 |
+
fig.add_trace(go.Scatter(
|
| 725 |
+
x=[node_x[source_idx], node_x[target_idx], None],
|
| 726 |
+
y=[node_y[source_idx], node_y[target_idx], None],
|
| 727 |
+
mode='lines',
|
| 728 |
+
line=dict(
|
| 729 |
+
width=2 * edge.get("weight", 1.0),
|
| 730 |
+
color='rgba(100, 100, 100, 0.5)'
|
| 731 |
+
),
|
| 732 |
+
hoverinfo='none',
|
| 733 |
+
showlegend=False
|
| 734 |
+
))
|
| 735 |
+
except (ValueError, IndexError):
|
| 736 |
+
continue
|
|
|
|
|
|
|
|
|
|
| 737 |
|
| 738 |
fig.update_layout(
|
| 739 |
+
title=f"<b>Incident Memory Graph ({len(nodes)} nodes)</b>",
|
| 740 |
+
showlegend=False,
|
| 741 |
height=600,
|
| 742 |
+
paper_bgcolor='white',
|
| 743 |
+
plot_bgcolor='white',
|
| 744 |
hovermode='closest',
|
| 745 |
+
xaxis=dict(
|
| 746 |
+
showgrid=False,
|
| 747 |
+
zeroline=False,
|
| 748 |
+
showticklabels=False,
|
| 749 |
+
range=[-1.5, 1.5]
|
| 750 |
+
),
|
| 751 |
+
yaxis=dict(
|
| 752 |
+
showgrid=False,
|
| 753 |
+
zeroline=False,
|
| 754 |
+
showticklabels=False,
|
| 755 |
+
range=[-1.5, 1.5]
|
| 756 |
+
),
|
| 757 |
+
margin=dict(l=50, r=50, t=80, b=50)
|
| 758 |
)
|
| 759 |
|
| 760 |
return fig
|
|
|
|
| 766 |
rows=2, cols=2,
|
| 767 |
subplot_titles=('Incident Frequency', 'Resolution Times',
|
| 768 |
'Success Rates', 'Pattern Correlation'),
|
| 769 |
+
vertical_spacing=0.15,
|
| 770 |
+
horizontal_spacing=0.15
|
| 771 |
)
|
| 772 |
|
| 773 |
# Sample data - in real app this would come from analysis
|
|
|
|
| 778 |
|
| 779 |
# Incident Frequency
|
| 780 |
fig.add_trace(
|
| 781 |
+
go.Bar(
|
| 782 |
+
x=patterns,
|
| 783 |
+
y=frequencies,
|
| 784 |
+
name='Frequency',
|
| 785 |
+
marker_color='#4ECDC4'
|
| 786 |
+
),
|
| 787 |
row=1, col=1
|
| 788 |
)
|
| 789 |
|
| 790 |
# Resolution Times
|
| 791 |
fig.add_trace(
|
| 792 |
+
go.Bar(
|
| 793 |
+
x=patterns,
|
| 794 |
+
y=resolution_times,
|
| 795 |
+
name='Resolution Time (min)',
|
| 796 |
+
marker_color='#45B7D1'
|
| 797 |
+
),
|
| 798 |
row=1, col=2
|
| 799 |
)
|
| 800 |
|
| 801 |
# Success Rates
|
| 802 |
fig.add_trace(
|
| 803 |
+
go.Bar(
|
| 804 |
+
x=patterns,
|
| 805 |
+
y=success_rates,
|
| 806 |
+
name='Success Rate %',
|
| 807 |
+
marker_color='#96CEB4'
|
| 808 |
+
),
|
| 809 |
row=2, col=1
|
| 810 |
)
|
| 811 |
|
|
|
|
| 819 |
])
|
| 820 |
|
| 821 |
fig.add_trace(
|
| 822 |
+
go.Heatmap(
|
| 823 |
+
z=corr_matrix,
|
| 824 |
+
x=patterns,
|
| 825 |
+
y=patterns,
|
| 826 |
+
colorscale='Blues',
|
| 827 |
+
showscale=True
|
| 828 |
+
),
|
| 829 |
row=2, col=2
|
| 830 |
)
|
| 831 |
|
| 832 |
fig.update_layout(
|
| 833 |
height=700,
|
| 834 |
showlegend=False,
|
| 835 |
+
title_text="<b>Pattern Analysis Dashboard</b>",
|
| 836 |
+
paper_bgcolor='white',
|
| 837 |
+
plot_bgcolor='white'
|
| 838 |
)
|
| 839 |
|
| 840 |
+
# Update axes
|
| 841 |
+
fig.update_xaxes(title_text="Pattern Type", row=1, col=1)
|
| 842 |
+
fig.update_yaxes(title_text="Frequency", row=1, col=1)
|
| 843 |
+
fig.update_xaxes(title_text="Pattern Type", row=1, col=2)
|
| 844 |
+
fig.update_yaxes(title_text="Time (minutes)", row=1, col=2)
|
| 845 |
+
fig.update_xaxes(title_text="Pattern Type", row=2, col=1)
|
| 846 |
+
fig.update_yaxes(title_text="Success Rate (%)", row=2, col=1)
|
| 847 |
+
|
| 848 |
return fig
|
| 849 |
|
| 850 |
# ===========================================
|
|
|
|
| 1207 |
return temp_file.name
|
| 1208 |
|
| 1209 |
# ===========================================
|
| 1210 |
+
# MAIN INTERFACE (FIXED)
|
| 1211 |
# ===========================================
|
| 1212 |
|
| 1213 |
def create_interface() -> gr.Blocks:
|
|
|
|
| 1223 |
h1, h2, h3 { color: #1a365d !important; }
|
| 1224 |
.critical { color: #FF6B6B !important; font-weight: bold; }
|
| 1225 |
.success { color: #4ECDC4 !important; font-weight: bold; }
|
| 1226 |
+
.plot-container { background: white !important; border-radius: 10px; padding: 10px; }
|
| 1227 |
"""
|
| 1228 |
|
| 1229 |
with gr.Blocks(
|
| 1230 |
title="๐ ARF Investor Demo v3.8.0",
|
| 1231 |
+
theme=gr.themes.Soft(primary_hue="blue", secondary_hue="teal"),
|
| 1232 |
css=custom_css
|
| 1233 |
) as demo:
|
| 1234 |
|
|
|
|
| 1280 |
with gr.Column(scale=2):
|
| 1281 |
# Visualization
|
| 1282 |
gr.Markdown("### ๐ Incident Timeline")
|
| 1283 |
+
timeline_output = gr.Plot(
|
| 1284 |
+
value=viz_engine.create_incident_timeline(),
|
| 1285 |
+
label="Timeline Visualization"
|
| 1286 |
+
)
|
| 1287 |
|
| 1288 |
# Action Section
|
| 1289 |
gr.Markdown("### โก Take Action")
|
|
|
|
| 1322 |
with gr.Column():
|
| 1323 |
# Business Dashboard
|
| 1324 |
gr.Markdown("### ๐ Executive Business Dashboard")
|
| 1325 |
+
dashboard_output = gr.Plot(
|
| 1326 |
+
value=viz_engine.create_business_dashboard(),
|
| 1327 |
+
label="Business Dashboard"
|
| 1328 |
+
)
|
| 1329 |
|
| 1330 |
# ROI Calculator
|
| 1331 |
gr.Markdown("### ๐งฎ Interactive ROI Calculator")
|
|
|
|
| 1397 |
)
|
| 1398 |
|
| 1399 |
gr.Markdown("### ๐ Visual History")
|
| 1400 |
+
execution_chart = gr.Plot(
|
| 1401 |
+
value=viz_engine.create_execution_history_chart(audit_manager),
|
| 1402 |
+
label="Cost Savings Chart"
|
| 1403 |
+
)
|
| 1404 |
|
| 1405 |
# AI Analysis Results
|
| 1406 |
gr.Markdown("### ๐ง AI Pattern Analysis")
|
|
|
|
| 1423 |
|
| 1424 |
# Memory Graph Visualization
|
| 1425 |
gr.Markdown("### ๐ง Memory Graph")
|
| 1426 |
+
memory_graph = gr.Plot(
|
| 1427 |
+
value=viz_engine.create_memory_graph(audit_manager),
|
| 1428 |
+
label="Memory Graph"
|
| 1429 |
+
)
|
| 1430 |
|
| 1431 |
# Export Area
|
| 1432 |
gr.Markdown("### ๐ค Export & Analytics")
|
|
|
|
| 1558 |
auto_layout = gr.Checkbox(label="Auto-Layout", value=True)
|
| 1559 |
|
| 1560 |
# Graph Visualization
|
| 1561 |
+
memory_graph_plot = gr.Plot(
|
| 1562 |
+
value=viz_engine.create_memory_graph(audit_manager),
|
| 1563 |
+
label="Memory Graph Visualization"
|
| 1564 |
+
)
|
| 1565 |
|
| 1566 |
# Node Details
|
| 1567 |
gr.Markdown("### ๐ Selected Node Details")
|
|
|
|
| 1828 |
auto_layout=auto_layout
|
| 1829 |
)
|
| 1830 |
|
| 1831 |
+
# Connect all graph controls
|
| 1832 |
+
graph_type.change(
|
| 1833 |
+
fn=update_graph_view,
|
| 1834 |
+
inputs=[graph_type, show_weights, auto_layout],
|
| 1835 |
+
outputs=[memory_graph_plot]
|
| 1836 |
+
)
|
| 1837 |
+
|
| 1838 |
+
show_weights.change(
|
| 1839 |
+
fn=update_graph_view,
|
| 1840 |
+
inputs=[graph_type, show_weights, auto_layout],
|
| 1841 |
+
outputs=[memory_graph_plot]
|
| 1842 |
+
)
|
| 1843 |
+
|
| 1844 |
+
auto_layout.change(
|
| 1845 |
+
fn=update_graph_view,
|
| 1846 |
+
inputs=[graph_type, show_weights, auto_layout],
|
| 1847 |
+
outputs=[memory_graph_plot]
|
| 1848 |
+
)
|
| 1849 |
|
| 1850 |
def search_memory(query: str) -> Tuple[List[List[str]], str]:
|
| 1851 |
"""Search memory"""
|
|
|
|
| 1891 |
)
|
| 1892 |
|
| 1893 |
# ===========================================
|
| 1894 |
+
# INITIALIZATION - FIXED
|
| 1895 |
# ===========================================
|
| 1896 |
|
| 1897 |
+
# Initialize with default visualizations
|
| 1898 |
demo.load(
|
| 1899 |
fn=lambda: (
|
| 1900 |
viz_engine.create_business_dashboard(),
|