petter2025 commited on
Commit
d203412
·
verified ·
1 Parent(s): b0546d3

Update ui/components.py

Browse files
Files changed (1) hide show
  1. ui/components.py +120 -427
ui/components.py CHANGED
@@ -1,19 +1,41 @@
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
@@ -22,27 +44,33 @@ class MockHealingIntent:
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"},
@@ -50,438 +78,103 @@ def create_arf_enhanced_timeline(incident_data: Dict[str, Any], healing_intents:
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
 
1
  """
2
  Enhanced components with real ARF integration
3
+ (Streamlit-optional, Hugging Face safe)
4
  """
5
+ from __future__ import annotations
6
+
7
+ import logging
8
+ from datetime import datetime
9
+ from typing import List, Dict, Any
10
+ import time
11
+
12
  import plotly.graph_objects as go
13
  import plotly.express as px
 
14
  import pandas as pd
15
  import numpy as np
 
 
 
16
 
17
+ logger = logging.getLogger(__name__)
18
+
19
+ # --- OPTIONAL Streamlit import (HF-safe) ---
20
+ try:
21
+ import streamlit as st # type: ignore
22
+ except Exception:
23
+ st = None
24
+ logger.info("Streamlit not available; ui.components running in headless mode.")
25
+
26
+
27
+ # -----------------------------
28
+ # Helpers
29
+ # -----------------------------
30
+ def _require_streamlit() -> bool:
31
+ """Guard to prevent crashes when Streamlit is unavailable."""
32
+ return st is not None
33
+
34
+
35
+ # -----------------------------
36
+ # Mock ARF object (demo-safe)
37
+ # -----------------------------
38
  class MockHealingIntent:
 
39
  def __init__(self, action, component, confidence, status, rag_similarity_score=None):
40
  self.action = action
41
  self.component = component
 
44
  self.rag_similarity_score = rag_similarity_score
45
  self.deterministic_id = f"intent_{int(time.time())}"
46
  self.created_at = time.time()
47
+
48
  def get_execution_summary(self):
49
  return {
50
  "intent_id": self.deterministic_id,
51
  "action": self.action,
52
  "component": self.component,
53
  "confidence": self.confidence,
54
+ "status": self.status.value if hasattr(self.status, "value") else self.status,
55
+ "rag_similarity_score": self.rag_similarity_score,
56
  }
57
 
58
+
59
+ # -----------------------------
60
+ # UI Components (SAFE)
61
+ # -----------------------------
62
+ def create_arf_enhanced_timeline(
63
+ incident_data: Dict[str, Any],
64
+ healing_intents: List[Dict[str, Any]] | None = None,
65
+ ):
66
+ if not _require_streamlit():
67
+ return
68
+
69
  col1, col2 = st.columns([2, 1])
70
+
71
  with col1:
72
  st.markdown("### 📈 ARF-Enhanced Incident Timeline")
73
+
 
74
  events = [
75
  {"time": "-5m", "event": "📡 Alert Triggered", "phase": "detection", "color": "#FF6B6B"},
76
  {"time": "-4m", "event": "🧠 ARF Analysis Started", "phase": "analysis", "color": "#4ECDC4"},
 
78
  {"time": "-2.5m", "event": "🎯 Pattern Detection", "phase": "pattern", "color": "#9D4EDD"},
79
  {"time": "-1.5m", "event": "💡 HealingIntent Generated", "phase": "intent", "color": "#FFD166"},
80
  {"time": "-1m", "event": "⚡ MCP Execution", "phase": "execution", "color": "#06D6A0"},
81
+ {"time": "Now", "event": "✅ Resolution Complete", "phase": "resolution", "color": "#118AB2"},
82
  ]
83
+
 
84
  fig = go.Figure()
85
+
86
+ fig.add_trace(
87
+ go.Scatter(
88
+ x=list(range(len(events))),
89
+ y=[0] * len(events),
90
+ mode="lines+markers",
91
+ marker=dict(size=16, color=[e["color"] for e in events]),
92
+ line=dict(width=2),
93
+ hovertext=[e["event"] for e in events],
94
+ hoverinfo="text",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  )
96
+ )
97
+
98
  fig.update_layout(
99
  height=250,
100
  showlegend=False,
101
+ xaxis=dict(visible=False),
102
+ yaxis=dict(visible=False),
103
+ margin=dict(l=20, r=20, t=20, b=20),
 
 
 
 
 
 
 
 
 
 
 
 
104
  )
105
+
106
  st.plotly_chart(fig, use_container_width=True)
107
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  with col2:
109
  st.markdown("### 🎯 ARF Pattern Detection")
110
+
111
+ rag_score = (
112
+ healing_intents[0].get("rag_similarity_score", 0.85)
113
+ if healing_intents
114
+ else 0.85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  )
116
+
117
+ fig = go.Figure(
118
+ go.Indicator(
119
+ mode="gauge+number",
120
+ value=rag_score * 100,
121
+ gauge={"axis": {"range": [0, 100]}},
122
+ title={"text": "RAG Similarity"},
123
+ )
124
+ )
125
+
126
+ fig.update_layout(height=200)
127
  st.plotly_chart(fig, use_container_width=True)
128
+
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  def create_healing_intent_visualizer(healing_intent: Dict[str, Any]):
131
+ if not _require_streamlit():
132
+ return
133
+
134
  st.markdown("### 💡 ARF HealingIntent")
135
+
136
+ confidence = healing_intent.get("confidence", 0.85)
137
+
138
+ fig = go.Figure(
139
+ go.Indicator(
 
 
 
140
  mode="gauge+number",
141
  value=confidence * 100,
142
+ gauge={"axis": {"range": [0, 100]}},
143
+ title={"text": "Confidence"},
144
+ )
145
+ )
146
+
147
+ fig.update_layout(height=180)
148
+ st.plotly_chart(fig, use_container_width=True)
149
+
150
+ st.json(healing_intent)
151
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
  def create_rag_similarity_panel(query: str, similar_incidents: List[Dict[str, Any]]):
154
+ if not _require_streamlit():
155
+ return
156
+
157
  st.markdown("### 🔍 RAG Similarity Search")
158
+
159
  if not similar_incidents:
160
+ st.info("No similar incidents found")
161
  return
162
+
163
+ df = pd.DataFrame(similar_incidents)
164
+ st.dataframe(df, use_container_width=True)
165
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
  def create_learning_engine_panel(learning_stats: Dict[str, Any]):
168
+ if not _require_streamlit():
169
+ return
170
+
171
  st.markdown("### 🧠 ARF Learning Engine")
172
+ st.json(learning_stats)
173
+
174
+
175
+ def create_execution_mode_toggle(current_mode: str = "advisory") -> str:
176
+ if not _require_streamlit():
177
+ return current_mode
178
+
179
+ modes = ["advisory", "approval", "autonomous"]
180
+ return st.selectbox("Execution Mode", modes, index=modes.index(current_mode))