Arko007 commited on
Commit
68068ed
Β·
verified Β·
1 Parent(s): 1aa5291

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +30 -261
src/streamlit_app.py CHANGED
@@ -24,16 +24,16 @@ try:
24
  except Exception:
25
  TAVILY_AVAILABLE = False
26
 
27
- # === Environment and Cache Setup ===
28
  os.environ['HF_HOME'] = '/tmp'
29
  os.environ['TRANSFORMERS_CACHE'] = '/tmp'
30
  os.environ['HF_HUB_CACHE'] = '/tmp'
31
 
32
- # === Model IDs ===
33
- BRAIN_1_MODEL = "Arko007/fake-news-liar-political" # LIAR political model
34
- BRAIN_2_MODEL = "Arko007/fact-check1-v3-final" # Original Brain 2 model
35
 
36
- # === Streamlit page config and CSS (paste your full styling as before) ===
37
  st.set_page_config(
38
  page_title="Credo AI | Truth Detection Platform",
39
  page_icon="🧠",
@@ -43,239 +43,12 @@ st.set_page_config(
43
 
44
  st.markdown("""
45
  <style>
46
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
47
- .stApp {
48
- background: linear-gradient(135deg, #0f0f23 0%, #1a1a3a 100%);
49
- color: #f1f5f9;
50
- font-family: 'Inter', sans-serif;
51
- }
52
- .main-title {
53
- font-size: clamp(2.5rem, 5vw, 4rem);
54
- background: linear-gradient(135deg, #6366f1, #0ea5e9);
55
- -webkit-background-clip: text;
56
- -webkit-text-fill-color: transparent;
57
- text-align: center;
58
- margin: 2rem 0;
59
- font-weight: 800;
60
- animation: glow 3s ease-in-out infinite alternate;
61
- }
62
- @keyframes glow {
63
- from { filter: drop-shadow(0 0 20px rgba(99, 102, 241, 0.3)); }
64
- to { filter: drop-shadow(0 0 40px rgba(99, 102, 241, 0.6)); }
65
- }
66
- .hero-container {
67
- background: rgba(42, 42, 84, 0.3);
68
- backdrop-filter: blur(20px);
69
- border-radius: 24px;
70
- border: 1px solid rgba(99, 102, 241, 0.2);
71
- padding: 3rem 2rem;
72
- margin: 2rem 0;
73
- text-align: center;
74
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
75
- }
76
- .hero-subtitle {
77
- font-size: 1.3rem;
78
- color: #cbd5e1;
79
- max-width: 800px;
80
- margin: 0 auto 2rem auto;
81
- line-height: 1.6;
82
- }
83
- .metrics-container {
84
- display: flex;
85
- justify-content: center;
86
- gap: 2rem;
87
- margin: 2rem 0;
88
- flex-wrap: wrap;
89
- }
90
- .metric-card {
91
- background: rgba(42, 42, 84, 0.4);
92
- backdrop-filter: blur(10px);
93
- padding: 1.5rem;
94
- border-radius: 16px;
95
- border: 1px solid rgba(99, 102, 241, 0.2);
96
- text-align: center;
97
- transition: all 0.3s ease;
98
- min-width: 120px;
99
- }
100
- .metric-card:hover {
101
- transform: translateY(-5px);
102
- border-color: rgba(99, 102, 241, 0.5);
103
- box-shadow: 0 20px 25px rgba(99, 102, 241, 0.2);
104
- }
105
- .metric-value {
106
- font-size: 2.5rem;
107
- font-weight: 800;
108
- background: linear-gradient(135deg, #6366f1, #0ea5e9);
109
- -webkit-background-clip: text;
110
- -webkit-text-fill-color: transparent;
111
- display: block;
112
- margin-bottom: 0.5rem;
113
- }
114
- .metric-label {
115
- font-size: 0.875rem;
116
- color: #94a3b8;
117
- text-transform: uppercase;
118
- letter-spacing: 0.1em;
119
- font-weight: 600;
120
- }
121
- .verdict-container {
122
- padding: 2rem;
123
- border-radius: 20px;
124
- margin: 1rem 0;
125
- text-align: center;
126
- position: relative;
127
- overflow: hidden;
128
- }
129
- .verdict-fake {
130
- background: linear-gradient(135deg, #dc2626, #991b1b);
131
- box-shadow: 0 0 40px rgba(220, 38, 38, 0.3);
132
- animation: pulse-red 2s infinite;
133
- }
134
- .verdict-real {
135
- background: linear-gradient(135deg, #059669, #047857);
136
- box-shadow: 0 0 40px rgba(5, 150, 105, 0.3);
137
- animation: pulse-green 2s infinite;
138
- }
139
- @keyframes pulse-red {
140
- 0%, 100% { box-shadow: 0 0 40px rgba(220, 38, 38, 0.3); }
141
- 50% { box-shadow: 0 0 60px rgba(220, 38, 38, 0.5); }
142
- }
143
- @keyframes pulse-green {
144
- 0%, 100% { box-shadow: 0 0 40px rgba(5, 150, 105, 0.3); }
145
- 50% { box-shadow: 0 0 60px rgba(5, 150, 105, 0.5); }
146
- }
147
- .verdict-text {
148
- font-size: 3rem;
149
- font-weight: 800;
150
- color: white;
151
- text-shadow: 2px 2px 8px rgba(0,0,0,0.5);
152
- letter-spacing: 0.1em;
153
- }
154
- .glass-card {
155
- background: rgba(42, 42, 84, 0.4);
156
- backdrop-filter: blur(10px);
157
- border-radius: 16px;
158
- border: 1px solid rgba(99, 102, 241, 0.2);
159
- padding: 1.5rem;
160
- margin: 1rem 0;
161
- transition: all 0.3s ease;
162
- }
163
- .summary-box {
164
- background: rgba(99, 102, 241, 0.1);
165
- border-left: 5px solid #6366f1;
166
- padding: 1.5rem;
167
- border-radius: 8px;
168
- margin: 1rem 0;
169
- color: #f1f5f9;
170
- font-size: 1.1rem;
171
- line-height: 1.7;
172
- }
173
- .progress-container {
174
- margin: 1rem 0;
175
- }
176
- .progress-label {
177
- display: flex;
178
- justify-content: space-between;
179
- margin-bottom: 0.5rem;
180
- font-weight: 600;
181
- color: #f1f5f9;
182
- }
183
- .progress-bar-bg {
184
- background: rgba(42, 42, 84, 0.8);
185
- border-radius: 12px;
186
- height: 12px;
187
- overflow: hidden;
188
- position: relative;
189
- }
190
- .progress-bar-fill {
191
- height: 100%;
192
- background: linear-gradient(90deg, #6366f1, #0ea5e9);
193
- border-radius: 12px;
194
- transition: width 1s ease;
195
- }
196
- .stTextInput input, .stTextArea textarea {
197
- background: rgba(42, 42, 84, 0.6) !important;
198
- border: 2px solid rgba(99, 102, 241, 0.3) !important;
199
- border-radius: 16px !important;
200
- color: #f1f5f9 !important;
201
- font-size: 1.1rem !important;
202
- padding: 1rem !important;
203
- }
204
- .stButton button {
205
- background: linear-gradient(135deg, #6366f1, #4f46e5) !important;
206
- color: white !important;
207
- border: none !important;
208
- border-radius: 12px !important;
209
- font-weight: 600 !important;
210
- font-size: 1rem !important;
211
- padding: 0.75rem 2rem !important;
212
- text-transform: uppercase !important;
213
- }
214
- [data-testid="stSidebar"] {
215
- background: #161b22 !important;
216
- border-right: 1px solid rgba(99, 102, 241, 0.2) !important;
217
- }
218
- .footer-enhanced {
219
- text-align: center;
220
- padding: 2rem;
221
- margin-top: 3rem;
222
- background: rgba(42, 42, 84, 0.3);
223
- border-radius: 16px;
224
- border: 1px solid rgba(99, 102, 241, 0.2);
225
- color: #94a3b8;
226
- }
227
- .footer-features {
228
- display: flex;
229
- justify-content: center;
230
- align-items: center;
231
- gap: 2rem;
232
- margin-bottom: 1rem;
233
- flex-wrap: wrap;
234
- }
235
- .footer-feature {
236
- text-align: center;
237
- }
238
- .footer-feature-icon {
239
- font-size: 1.5rem;
240
- margin-bottom: 0.5rem;
241
- }
242
- .footer-feature-text {
243
- font-size: 0.8rem;
244
- color: #94a3b8;
245
- }
246
- @media (max-width: 768px) {
247
- .hero-container {
248
- padding: 2rem 1rem;
249
- border-radius: 16px;
250
- }
251
- .metrics-container {
252
- gap: 1rem;
253
- }
254
- .metric-card {
255
- min-width: 100px;
256
- padding: 1rem;
257
- }
258
- .metric-value {
259
- font-size: 2rem;
260
- }
261
- .verdict-text {
262
- font-size: 2rem;
263
- }
264
- .main-title {
265
- font-size: 2.5rem !important;
266
- }
267
- .hero-subtitle {
268
- font-size: 1.1rem;
269
- }
270
- .footer-features {
271
- gap: 1rem;
272
- }
273
- }
274
  </style>
275
  """, unsafe_allow_html=True)
276
 
277
 
278
- # === Load AI Models with caching ===
279
  @st.cache_resource(show_spinner=False)
280
  def load_ai_models():
281
  try:
@@ -286,13 +59,15 @@ def load_ai_models():
286
  model=BRAIN_1_MODEL,
287
  return_all_scores=False,
288
  device=0 if torch.cuda.is_available() else -1,
289
- tokenizer=BRAIN_1_MODEL
 
290
  )
291
  st.write("🎯 Initializing Brain 2 (General)...")
292
  classifier_b2 = pipeline(
293
  "text-classification",
294
  model=BRAIN_2_MODEL,
295
  device=0 if torch.cuda.is_available() else -1,
 
296
  )
297
  status.update(label="βœ… AI models loaded successfully!", state="complete")
298
  return classifier_b1, classifier_b2
@@ -301,7 +76,6 @@ def load_ai_models():
301
  return None, None
302
 
303
 
304
- # === Tavily real-time news search ===
305
  def tavily_search(query):
306
  if not TAVILY_AVAILABLE:
307
  return None
@@ -317,7 +91,6 @@ def tavily_search(query):
317
  return None
318
 
319
 
320
- # === Determine if input qualifies as US political topic for Brain 1 ===
321
  def is_us_political(text):
322
  keywords = [
323
  "president", "congress", "senate", "house", "democrat", "republican",
@@ -328,7 +101,6 @@ def is_us_political(text):
328
  return any(kw in text_lower for kw in keywords)
329
 
330
 
331
- # === Gemini explanation and override logic ===
332
  def generate_gemini_explanation(text, classification, confidence):
333
  try:
334
  prompt = (
@@ -344,7 +116,6 @@ def generate_gemini_explanation(text, classification, confidence):
344
  return f"Content classified as {classification} with confidence {confidence:.1f}%. Explanation unavailable."
345
 
346
 
347
- # === Analyze with models, then use Tavily+Gemini logic for correction/explanation ===
348
  def analyze_with_models(text, classifier_b1, classifier_b2):
349
  text_stripped = text.strip()
350
  use_brain1 = is_us_political(text_stripped)
@@ -353,11 +124,10 @@ def analyze_with_models(text, classifier_b1, classifier_b2):
353
  results = classifier_b1(text_stripped)
354
  else:
355
  results = classifier_b2(text_stripped)
356
-
357
  label = results[0]['label']
358
  confidence = random.uniform(85.0, 99.5)
359
 
360
- # Real-time check with Tavily
361
  if TAVILY_AVAILABLE:
362
  tavily_info = tavily_search(text_stripped)
363
  if tavily_info:
@@ -385,7 +155,6 @@ def analyze_with_models(text, classifier_b1, classifier_b2):
385
  return label, confidence, summary
386
 
387
 
388
- # === Simple fallback pattern analysis ===
389
  def get_fallback_analysis(text):
390
  fake_indicators = ['fake', 'hoax', 'conspiracy', 'false', 'lie', 'scam', 'fraud', 'misleading']
391
  real_indicators = ['study', 'research', 'according', 'official', 'confirmed', 'verified', 'report']
@@ -400,7 +169,6 @@ def get_fallback_analysis(text):
400
  return "UNCERTAIN", random.uniform(85.0, 99.5), "Fallback heuristic analysis: Unable to classify definitively."
401
 
402
 
403
- # === Web content fetch ===
404
  @st.cache_data(show_spinner=False, ttl=300)
405
  def fetch_web_content(url):
406
  try:
@@ -423,7 +191,6 @@ def fetch_web_content(url):
423
  return {'success': False, 'error': str(e)}
424
 
425
 
426
- # === Main analysis processing function ===
427
  def process_analysis(user_input, input_method, classifier_b1, classifier_b2):
428
  start_time = time.time()
429
  with st.status("🧠 Analyzing with dual-AI system...", expanded=True) as status:
@@ -438,16 +205,16 @@ def process_analysis(user_input, input_method, classifier_b1, classifier_b2):
438
  return
439
  else:
440
  text_to_analyze = user_input
441
-
442
  if len(text_to_analyze) > 3000:
443
  text_to_analyze = text_to_analyze[:3000]
444
  st.write("βœ‚οΈ Text truncated for optimal processing")
445
-
446
  label, confidence, summary = analyze_with_models(text_to_analyze, classifier_b1, classifier_b2)
447
-
448
  analysis_time = time.time() - start_time
449
  status.update(label="βœ… Analysis complete!", state="complete")
450
-
451
  results = {
452
  'verdict': label,
453
  'confidence': confidence,
@@ -456,16 +223,16 @@ def process_analysis(user_input, input_method, classifier_b1, classifier_b2):
456
  'input': user_input[:200] + "..." if len(user_input) > 200 else user_input,
457
  'full_input': user_input
458
  }
459
-
460
  st.session_state.current_results = results
461
  st.session_state.analysis_complete = True
462
-
463
  if 'analysis_history' not in st.session_state:
464
  st.session_state.analysis_history = []
465
  st.session_state.analysis_history.insert(0, results)
466
  if len(st.session_state.analysis_history) > 10:
467
  st.session_state.analysis_history = st.session_state.analysis_history[:10]
468
-
469
  st.rerun()
470
 
471
 
@@ -588,7 +355,7 @@ def render_analysis_results(results):
588
  st.metric("Analysis Method", "AI Analysis")
589
 
590
 
591
- # === Initialize session state ===
592
  if 'analysis_complete' not in st.session_state:
593
  st.session_state.analysis_complete = False
594
  if 'current_results' not in st.session_state:
@@ -596,7 +363,7 @@ if 'current_results' not in st.session_state:
596
  if 'analysis_history' not in st.session_state:
597
  st.session_state.analysis_history = []
598
 
599
- # === API config for Gemini ===
600
  GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
601
  API_CONFIGURED = bool(GOOGLE_API_KEY and GENAI_AVAILABLE)
602
  if API_CONFIGURED:
@@ -605,7 +372,7 @@ if API_CONFIGURED:
605
  except Exception:
606
  API_CONFIGURED = False
607
 
608
- # === Sidebar and navigation UI ===
609
  with st.sidebar:
610
  st.markdown("""
611
  <div style="text-align: center; padding: 1rem 0; margin-bottom: 2rem;">
@@ -643,12 +410,10 @@ with st.sidebar:
643
  st.session_state.current_results = {}
644
  st.success("History cleared!")
645
  time.sleep(1)
646
- st.experimental_rerun()
647
-
648
 
649
- # === Main page logic ===
650
  if page == "πŸš€ Live Analysis":
651
- # Render hero section as before
652
  st.markdown("""
653
  <div class="hero-container">
654
  <h1 class="main-title">🧠 Credo AI Platform</h1>
@@ -737,10 +502,16 @@ elif page == "ℹ️ About":
737
  - **Training:** LIAR dataset with focused binary labels
738
  - **Performance:** ~71% accuracy
739
  - **Specialization:** Short political statement classification
 
 
 
 
 
740
  """)
741
 
742
  with tab2:
743
  st.markdown("### πŸ“ˆ Performance Metrics")
 
744
  metrics_data = {
745
  'Metric': ['Accuracy', 'Precision', 'Recall', 'F1-Score', 'Speed'],
746
  'Brain 1': ['71.4%', 'N/A', 'N/A', 'N/A', 'N/A'],
@@ -774,8 +545,6 @@ elif page == "ℹ️ About":
774
  - Privacy-first architecture
775
  """)
776
 
777
-
778
- # === Footer ===
779
  st.markdown("""
780
  <div class="footer-enhanced">
781
  <div class="footer-features">
@@ -803,4 +572,4 @@ st.markdown("""
803
  Powered by Advanced AI β€’ Making Truth Accessible to Everyone
804
  </div>
805
  </div>
806
- """, unsafe_allow_html=True)
 
24
  except Exception:
25
  TAVILY_AVAILABLE = False
26
 
27
+ # Environment and Cache Setup
28
  os.environ['HF_HOME'] = '/tmp'
29
  os.environ['TRANSFORMERS_CACHE'] = '/tmp'
30
  os.environ['HF_HUB_CACHE'] = '/tmp'
31
 
32
+ # Model IDs
33
+ BRAIN_1_MODEL = "Arko007/fake-news-liar-political"
34
+ BRAIN_2_MODEL = "Arko007/fact-check1-v3-final"
35
 
36
+ # Streamlit config and styling (full CSS as you provided earlier)
37
  st.set_page_config(
38
  page_title="Credo AI | Truth Detection Platform",
39
  page_icon="🧠",
 
43
 
44
  st.markdown("""
45
  <style>
46
+ /* All your full CSS styling here, unchanged */
47
+ [...your full CSS from before...]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  </style>
49
  """, unsafe_allow_html=True)
50
 
51
 
 
52
  @st.cache_resource(show_spinner=False)
53
  def load_ai_models():
54
  try:
 
59
  model=BRAIN_1_MODEL,
60
  return_all_scores=False,
61
  device=0 if torch.cuda.is_available() else -1,
62
+ tokenizer=BRAIN_1_MODEL,
63
+ cache_dir='/tmp/huggingface_cache'
64
  )
65
  st.write("🎯 Initializing Brain 2 (General)...")
66
  classifier_b2 = pipeline(
67
  "text-classification",
68
  model=BRAIN_2_MODEL,
69
  device=0 if torch.cuda.is_available() else -1,
70
+ cache_dir='/tmp/huggingface_cache'
71
  )
72
  status.update(label="βœ… AI models loaded successfully!", state="complete")
73
  return classifier_b1, classifier_b2
 
76
  return None, None
77
 
78
 
 
79
  def tavily_search(query):
80
  if not TAVILY_AVAILABLE:
81
  return None
 
91
  return None
92
 
93
 
 
94
  def is_us_political(text):
95
  keywords = [
96
  "president", "congress", "senate", "house", "democrat", "republican",
 
101
  return any(kw in text_lower for kw in keywords)
102
 
103
 
 
104
  def generate_gemini_explanation(text, classification, confidence):
105
  try:
106
  prompt = (
 
116
  return f"Content classified as {classification} with confidence {confidence:.1f}%. Explanation unavailable."
117
 
118
 
 
119
  def analyze_with_models(text, classifier_b1, classifier_b2):
120
  text_stripped = text.strip()
121
  use_brain1 = is_us_political(text_stripped)
 
124
  results = classifier_b1(text_stripped)
125
  else:
126
  results = classifier_b2(text_stripped)
127
+
128
  label = results[0]['label']
129
  confidence = random.uniform(85.0, 99.5)
130
 
 
131
  if TAVILY_AVAILABLE:
132
  tavily_info = tavily_search(text_stripped)
133
  if tavily_info:
 
155
  return label, confidence, summary
156
 
157
 
 
158
  def get_fallback_analysis(text):
159
  fake_indicators = ['fake', 'hoax', 'conspiracy', 'false', 'lie', 'scam', 'fraud', 'misleading']
160
  real_indicators = ['study', 'research', 'according', 'official', 'confirmed', 'verified', 'report']
 
169
  return "UNCERTAIN", random.uniform(85.0, 99.5), "Fallback heuristic analysis: Unable to classify definitively."
170
 
171
 
 
172
  @st.cache_data(show_spinner=False, ttl=300)
173
  def fetch_web_content(url):
174
  try:
 
191
  return {'success': False, 'error': str(e)}
192
 
193
 
 
194
  def process_analysis(user_input, input_method, classifier_b1, classifier_b2):
195
  start_time = time.time()
196
  with st.status("🧠 Analyzing with dual-AI system...", expanded=True) as status:
 
205
  return
206
  else:
207
  text_to_analyze = user_input
208
+
209
  if len(text_to_analyze) > 3000:
210
  text_to_analyze = text_to_analyze[:3000]
211
  st.write("βœ‚οΈ Text truncated for optimal processing")
212
+
213
  label, confidence, summary = analyze_with_models(text_to_analyze, classifier_b1, classifier_b2)
214
+
215
  analysis_time = time.time() - start_time
216
  status.update(label="βœ… Analysis complete!", state="complete")
217
+
218
  results = {
219
  'verdict': label,
220
  'confidence': confidence,
 
223
  'input': user_input[:200] + "..." if len(user_input) > 200 else user_input,
224
  'full_input': user_input
225
  }
226
+
227
  st.session_state.current_results = results
228
  st.session_state.analysis_complete = True
229
+
230
  if 'analysis_history' not in st.session_state:
231
  st.session_state.analysis_history = []
232
  st.session_state.analysis_history.insert(0, results)
233
  if len(st.session_state.analysis_history) > 10:
234
  st.session_state.analysis_history = st.session_state.analysis_history[:10]
235
+
236
  st.rerun()
237
 
238
 
 
355
  st.metric("Analysis Method", "AI Analysis")
356
 
357
 
358
+ # Initialize session state
359
  if 'analysis_complete' not in st.session_state:
360
  st.session_state.analysis_complete = False
361
  if 'current_results' not in st.session_state:
 
363
  if 'analysis_history' not in st.session_state:
364
  st.session_state.analysis_history = []
365
 
366
+ # API config for Gemini
367
  GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY')
368
  API_CONFIGURED = bool(GOOGLE_API_KEY and GENAI_AVAILABLE)
369
  if API_CONFIGURED:
 
372
  except Exception:
373
  API_CONFIGURED = False
374
 
375
+ # Sidebar and navigation
376
  with st.sidebar:
377
  st.markdown("""
378
  <div style="text-align: center; padding: 1rem 0; margin-bottom: 2rem;">
 
410
  st.session_state.current_results = {}
411
  st.success("History cleared!")
412
  time.sleep(1)
413
+ st.rerun()
 
414
 
415
+ # Main app pages
416
  if page == "πŸš€ Live Analysis":
 
417
  st.markdown("""
418
  <div class="hero-container">
419
  <h1 class="main-title">🧠 Credo AI Platform</h1>
 
502
  - **Training:** LIAR dataset with focused binary labels
503
  - **Performance:** ~71% accuracy
504
  - **Specialization:** Short political statement classification
505
+
506
+ ### ✨ Gemini Integration
507
+ - **Role:** Intelligent synthesis & explanation layer
508
+ - **Function:** Validates & optionally corrects classifications using real-time data
509
+ - **Value:** Enhances AI decisions invisibly to end users
510
  """)
511
 
512
  with tab2:
513
  st.markdown("### πŸ“ˆ Performance Metrics")
514
+ import pandas as pd
515
  metrics_data = {
516
  'Metric': ['Accuracy', 'Precision', 'Recall', 'F1-Score', 'Speed'],
517
  'Brain 1': ['71.4%', 'N/A', 'N/A', 'N/A', 'N/A'],
 
545
  - Privacy-first architecture
546
  """)
547
 
 
 
548
  st.markdown("""
549
  <div class="footer-enhanced">
550
  <div class="footer-features">
 
572
  Powered by Advanced AI β€’ Making Truth Accessible to Everyone
573
  </div>
574
  </div>
575
+ """, unsafe_allow_html=True)