Update src/streamlit_app.py
Browse files- src/streamlit_app.py +45 -138
src/streamlit_app.py
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import streamlit as st
|
| 2 |
import torch
|
| 3 |
from transformers import pipeline
|
|
@@ -6,7 +16,6 @@ import numpy as np
|
|
| 6 |
import time
|
| 7 |
import requests
|
| 8 |
from bs4 import BeautifulSoup
|
| 9 |
-
import os
|
| 10 |
import json
|
| 11 |
import re
|
| 12 |
from datetime import datetime
|
|
@@ -17,7 +26,6 @@ try:
|
|
| 17 |
GENAI_AVAILABLE = True
|
| 18 |
except ImportError:
|
| 19 |
GENAI_AVAILABLE = False
|
| 20 |
-
st.warning("Google Generative AI not available. Summary features will be limited.")
|
| 21 |
|
| 22 |
# ==============================================================================
|
| 23 |
# π¨ STREAMLIT CONFIGURATION
|
|
@@ -40,7 +48,6 @@ if GOOGLE_API_KEY and GENAI_AVAILABLE:
|
|
| 40 |
API_CONFIGURED = True
|
| 41 |
except Exception as e:
|
| 42 |
API_CONFIGURED = False
|
| 43 |
-
st.error(f"API configuration failed: {e}")
|
| 44 |
else:
|
| 45 |
API_CONFIGURED = False
|
| 46 |
|
|
@@ -289,37 +296,6 @@ def load_custom_css():
|
|
| 289 |
border-right: 1px solid rgba(99, 102, 241, 0.2) !important;
|
| 290 |
}
|
| 291 |
|
| 292 |
-
.notification {
|
| 293 |
-
padding: 1rem 1.5rem;
|
| 294 |
-
border-radius: 12px;
|
| 295 |
-
margin: 1rem 0;
|
| 296 |
-
font-weight: 500;
|
| 297 |
-
}
|
| 298 |
-
|
| 299 |
-
.notification-success {
|
| 300 |
-
background: linear-gradient(135deg, #10b981, #047857);
|
| 301 |
-
color: white;
|
| 302 |
-
border-left: 4px solid #10b981;
|
| 303 |
-
}
|
| 304 |
-
|
| 305 |
-
.notification-error {
|
| 306 |
-
background: linear-gradient(135deg, #ef4444, #dc2626);
|
| 307 |
-
color: white;
|
| 308 |
-
border-left: 4px solid #ef4444;
|
| 309 |
-
}
|
| 310 |
-
|
| 311 |
-
.notification-info {
|
| 312 |
-
background: linear-gradient(135deg, #0ea5e9, #0284c7);
|
| 313 |
-
color: white;
|
| 314 |
-
border-left: 4px solid #0ea5e9;
|
| 315 |
-
}
|
| 316 |
-
|
| 317 |
-
.notification-warning {
|
| 318 |
-
background: linear-gradient(135deg, #f59e0b, #d97706);
|
| 319 |
-
color: white;
|
| 320 |
-
border-left: 4px solid #f59e0b;
|
| 321 |
-
}
|
| 322 |
-
|
| 323 |
.footer-enhanced {
|
| 324 |
text-align: center;
|
| 325 |
padding: 2rem;
|
|
@@ -417,24 +393,27 @@ BRAIN_2_MODEL = "Arko007/fact-check1-v3-final"
|
|
| 417 |
|
| 418 |
@st.cache_resource(show_spinner=False)
|
| 419 |
def load_ai_models():
|
| 420 |
-
"""Load and cache AI models"""
|
| 421 |
try:
|
| 422 |
with st.spinner("π§ Loading AI models..."):
|
| 423 |
-
# Load models with CPU device
|
| 424 |
classifier_b1 = pipeline(
|
| 425 |
"text-classification",
|
| 426 |
model=BRAIN_1_MODEL,
|
| 427 |
return_all_scores=True,
|
| 428 |
-
device=-1,
|
|
|
|
| 429 |
model_kwargs={"torch_dtype": torch.float32}
|
| 430 |
)
|
| 431 |
classifier_b2 = pipeline(
|
| 432 |
"text-classification",
|
| 433 |
model=BRAIN_2_MODEL,
|
| 434 |
-
device=-1,
|
|
|
|
| 435 |
model_kwargs={"torch_dtype": torch.float32}
|
| 436 |
)
|
| 437 |
return classifier_b1, classifier_b2
|
|
|
|
| 438 |
except Exception as e:
|
| 439 |
st.error(f"π΄ Model loading failed: {str(e)}")
|
| 440 |
return None, None
|
|
@@ -544,11 +523,11 @@ def get_ai_summary(text_data, brain_1_results, brain_2_result, url=None):
|
|
| 544 |
return f"Analysis complete: {brain_2_result['label']} verdict with {brain_2_result['score']:.1%} confidence. Primary nuance: {b1_top['label'].replace('-', ' ').title()}."
|
| 545 |
|
| 546 |
# ==============================================================================
|
| 547 |
-
# π¨ UI COMPONENTS
|
| 548 |
# ==============================================================================
|
| 549 |
def render_hero_section():
|
| 550 |
"""Render the hero section"""
|
| 551 |
-
|
| 552 |
<div class="hero-container">
|
| 553 |
<h1 class="main-title">π§ Credo AI Platform</h1>
|
| 554 |
<p class="hero-subtitle">
|
|
@@ -571,32 +550,18 @@ def render_hero_section():
|
|
| 571 |
</div>
|
| 572 |
</div>
|
| 573 |
</div>
|
| 574 |
-
"""
|
| 575 |
-
|
| 576 |
-
st.markdown(hero_html, unsafe_allow_html=True)
|
| 577 |
-
|
| 578 |
-
def show_notification(message, notification_type="info"):
|
| 579 |
-
"""Show styled notifications"""
|
| 580 |
-
notification_html = f"""
|
| 581 |
-
<div class="notification notification-{notification_type}">
|
| 582 |
-
{message}
|
| 583 |
-
</div>
|
| 584 |
-
"""
|
| 585 |
-
|
| 586 |
-
st.markdown(notification_html, unsafe_allow_html=True)
|
| 587 |
|
| 588 |
def render_analysis_results(results):
|
| 589 |
"""Render analysis results with enhanced styling"""
|
| 590 |
# AI Summary
|
| 591 |
st.markdown("### β¨ AI-Powered Analysis Summary")
|
| 592 |
|
| 593 |
-
|
| 594 |
<div class="summary-box">
|
| 595 |
{results['summary']}
|
| 596 |
</div>
|
| 597 |
-
"""
|
| 598 |
-
|
| 599 |
-
st.markdown(summary_html, unsafe_allow_html=True)
|
| 600 |
|
| 601 |
# Results columns
|
| 602 |
col1, col2 = st.columns(2, gap="large")
|
|
@@ -608,16 +573,14 @@ def render_analysis_results(results):
|
|
| 608 |
|
| 609 |
verdict_class = 'verdict-fake' if verdict == 'FAKE' else 'verdict-real'
|
| 610 |
|
| 611 |
-
|
| 612 |
<div class="verdict-container {verdict_class}">
|
| 613 |
<div class="verdict-text">{verdict}</div>
|
| 614 |
</div>
|
| 615 |
<div style="text-align: center; margin-top: 1rem; font-size: 1.5rem; font-weight: 600; color: #f1f5f9;">
|
| 616 |
{confidence:.1%} Confidence
|
| 617 |
</div>
|
| 618 |
-
"""
|
| 619 |
-
|
| 620 |
-
st.markdown(verdict_html, unsafe_allow_html=True)
|
| 621 |
|
| 622 |
with col2:
|
| 623 |
st.markdown("### π§ Nuance Analysis")
|
|
@@ -674,7 +637,7 @@ def process_analysis(user_input, input_method):
|
|
| 674 |
classifier_b1, classifier_b2 = load_ai_models()
|
| 675 |
|
| 676 |
if not classifier_b1 or not classifier_b2:
|
| 677 |
-
|
| 678 |
return
|
| 679 |
|
| 680 |
text_to_analyze = user_input
|
|
@@ -700,9 +663,9 @@ def process_analysis(user_input, input_method):
|
|
| 700 |
st.write(f"β
Successfully extracted {metadata['word_count']} words")
|
| 701 |
|
| 702 |
if metadata['word_count'] < 50:
|
| 703 |
-
|
| 704 |
else:
|
| 705 |
-
|
| 706 |
return
|
| 707 |
else:
|
| 708 |
metadata['word_count'] = len(text_to_analyze.split())
|
|
@@ -715,7 +678,7 @@ def process_analysis(user_input, input_method):
|
|
| 715 |
|
| 716 |
# Validate minimum content
|
| 717 |
if len(text_to_analyze.strip()) < 10:
|
| 718 |
-
|
| 719 |
return
|
| 720 |
|
| 721 |
# AI Analysis
|
|
@@ -738,7 +701,7 @@ def process_analysis(user_input, input_method):
|
|
| 738 |
status.update(label="β
Analysis complete!", state="complete")
|
| 739 |
|
| 740 |
except Exception as e:
|
| 741 |
-
|
| 742 |
return
|
| 743 |
|
| 744 |
# Store results
|
|
@@ -850,11 +813,11 @@ def render_analysis_interface():
|
|
| 850 |
# Input validation and processing
|
| 851 |
if analyze_btn:
|
| 852 |
if not user_input.strip():
|
| 853 |
-
|
| 854 |
elif len(user_input.strip()) < 10:
|
| 855 |
-
|
| 856 |
elif input_method == "URL/Website" and not user_input.startswith(('http://', 'https://')):
|
| 857 |
-
|
| 858 |
else:
|
| 859 |
process_analysis(user_input, input_method)
|
| 860 |
|
|
@@ -895,10 +858,10 @@ def export_results():
|
|
| 895 |
mime="application/json"
|
| 896 |
)
|
| 897 |
|
| 898 |
-
|
| 899 |
|
| 900 |
# ==============================================================================
|
| 901 |
-
# π― PAGE RENDERERS
|
| 902 |
# ==============================================================================
|
| 903 |
def render_live_analysis_page():
|
| 904 |
"""Main analysis page"""
|
|
@@ -912,10 +875,7 @@ def render_live_analysis_page():
|
|
| 912 |
|
| 913 |
# Show API status
|
| 914 |
if not API_CONFIGURED:
|
| 915 |
-
|
| 916 |
-
π <strong>Setup Required:</strong> Add your Google API key in Space Settings β Variables and Secrets β Add: <code>GOOGLE_API_KEY</code>
|
| 917 |
-
<br>The platform will work with basic summaries until the API key is configured.
|
| 918 |
-
""", "warning")
|
| 919 |
|
| 920 |
# Analysis interface
|
| 921 |
render_analysis_interface()
|
|
@@ -931,11 +891,7 @@ def render_history_page():
|
|
| 931 |
st.markdown("# π Analysis History")
|
| 932 |
|
| 933 |
if 'analysis_history' not in st.session_state or not st.session_state.analysis_history:
|
| 934 |
-
|
| 935 |
-
π <strong>No Analysis History</strong><br>
|
| 936 |
-
Your analysis history will appear here after you perform some fact-checking analyses.
|
| 937 |
-
Start by going to the Live Analysis page and analyzing some content!
|
| 938 |
-
""", "info")
|
| 939 |
return
|
| 940 |
|
| 941 |
history = st.session_state.analysis_history
|
|
@@ -1028,7 +984,7 @@ def render_about_page():
|
|
| 1028 |
"""About page with system information"""
|
| 1029 |
st.markdown("# π¬ About Credo AI")
|
| 1030 |
|
| 1031 |
-
|
| 1032 |
<div class="glass-card">
|
| 1033 |
<h2 style="color: #6366f1; margin-bottom: 1rem;">π Revolutionary Detection Technology</h2>
|
| 1034 |
<p style="font-size: 1.2rem; color: #cbd5e1; line-height: 1.7;">
|
|
@@ -1037,9 +993,7 @@ def render_about_page():
|
|
| 1037 |
to deliver unparalleled accuracy in misinformation detection.
|
| 1038 |
</p>
|
| 1039 |
</div>
|
| 1040 |
-
"""
|
| 1041 |
-
|
| 1042 |
-
st.markdown(about_html, unsafe_allow_html=True)
|
| 1043 |
|
| 1044 |
# Technical details in tabs
|
| 1045 |
tab1, tab2, tab3, tab4 = st.tabs(["π§ AI Architecture", "π Performance", "π¬ Technology", "π οΈ System Status"])
|
|
@@ -1081,23 +1035,7 @@ def render_about_page():
|
|
| 1081 |
df = pd.DataFrame(metrics_data)
|
| 1082 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
| 1083 |
|
| 1084 |
-
|
| 1085 |
-
π <strong>Industry Leading:</strong> Credo AI consistently outperforms
|
| 1086 |
-
single-model approaches by 15-25% across major misinformation datasets.
|
| 1087 |
-
""", "success")
|
| 1088 |
-
|
| 1089 |
-
st.markdown("#### π Model Comparison")
|
| 1090 |
-
st.markdown("""
|
| 1091 |
-
**vs. Traditional Approaches:**
|
| 1092 |
-
- 25% higher accuracy than single BERT models
|
| 1093 |
-
- 40% faster than ensemble methods
|
| 1094 |
-
- 60% better at detecting subtle misinformation
|
| 1095 |
-
|
| 1096 |
-
**vs. Rule-Based Systems:**
|
| 1097 |
-
- 300% improvement in contextual understanding
|
| 1098 |
-
- Near-zero false positives on factual content
|
| 1099 |
-
- Handles evolving misinformation tactics
|
| 1100 |
-
""")
|
| 1101 |
|
| 1102 |
with tab3:
|
| 1103 |
st.markdown("""
|
|
@@ -1120,7 +1058,6 @@ def render_about_page():
|
|
| 1120 |
**β‘ Performance & Optimization:**
|
| 1121 |
- Intelligent caching system
|
| 1122 |
- Memory-efficient processing
|
| 1123 |
-
- Async content fetching
|
| 1124 |
- Progressive loading
|
| 1125 |
- Mobile-responsive design
|
| 1126 |
|
|
@@ -1129,7 +1066,6 @@ def render_about_page():
|
|
| 1129 |
- Secure API key management
|
| 1130 |
- Privacy-first architecture
|
| 1131 |
- Local processing where possible
|
| 1132 |
-
- GDPR-compliant design
|
| 1133 |
""")
|
| 1134 |
|
| 1135 |
with tab4:
|
|
@@ -1145,9 +1081,9 @@ def render_about_page():
|
|
| 1145 |
# Model availability
|
| 1146 |
try:
|
| 1147 |
load_ai_models()
|
| 1148 |
-
model_status = "π’
|
| 1149 |
except:
|
| 1150 |
-
model_status = "π΄
|
| 1151 |
status_data.append(["AI Models", model_status])
|
| 1152 |
|
| 1153 |
# Memory usage
|
|
@@ -1165,31 +1101,6 @@ def render_about_page():
|
|
| 1165 |
status_df = pd.DataFrame(status_data, columns=['Component', 'Status'])
|
| 1166 |
st.dataframe(status_df, use_container_width=True, hide_index=True)
|
| 1167 |
|
| 1168 |
-
st.markdown("#### π Performance Metrics")
|
| 1169 |
-
perf_cols = st.columns(3)
|
| 1170 |
-
|
| 1171 |
-
with perf_cols[0]:
|
| 1172 |
-
if 'analysis_history' in st.session_state:
|
| 1173 |
-
avg_time = sum(h.get('metadata', {}).get('analysis_time', 0) for h in st.session_state.analysis_history)
|
| 1174 |
-
avg_time = avg_time / len(st.session_state.analysis_history) if st.session_state.analysis_history else 0
|
| 1175 |
-
st.metric("Avg Analysis Time", f"{avg_time:.2f}s")
|
| 1176 |
-
else:
|
| 1177 |
-
st.metric("Avg Analysis Time", "No data")
|
| 1178 |
-
|
| 1179 |
-
with perf_cols[1]:
|
| 1180 |
-
if 'analysis_history' in st.session_state and st.session_state.analysis_history:
|
| 1181 |
-
total_analyses = len(st.session_state.analysis_history)
|
| 1182 |
-
st.metric("Total Analyses", total_analyses)
|
| 1183 |
-
else:
|
| 1184 |
-
st.metric("Total Analyses", 0)
|
| 1185 |
-
|
| 1186 |
-
with perf_cols[2]:
|
| 1187 |
-
if 'analysis_history' in st.session_state and st.session_state.analysis_history:
|
| 1188 |
-
success_rate = len([h for h in st.session_state.analysis_history if h.get('b2_label')]) / len(st.session_state.analysis_history) * 100
|
| 1189 |
-
st.metric("Success Rate", f"{success_rate:.1f}%")
|
| 1190 |
-
else:
|
| 1191 |
-
st.metric("Success Rate", "100%")
|
| 1192 |
-
|
| 1193 |
# ==============================================================================
|
| 1194 |
# π MAIN APPLICATION
|
| 1195 |
# ==============================================================================
|
|
@@ -1201,14 +1112,12 @@ if 'analysis_history' not in st.session_state:
|
|
| 1201 |
# Sidebar navigation
|
| 1202 |
with st.sidebar:
|
| 1203 |
# Sidebar header
|
| 1204 |
-
|
| 1205 |
<div style="text-align: center; padding: 1rem 0; margin-bottom: 2rem;">
|
| 1206 |
<h2 style="color: #6366f1; margin: 0;">π§ Credo AI</h2>
|
| 1207 |
<p style="color: #94a3b8; margin: 0.5rem 0 0 0; font-size: 0.9rem;">Truth Detection Platform</p>
|
| 1208 |
</div>
|
| 1209 |
-
"""
|
| 1210 |
-
|
| 1211 |
-
st.markdown(sidebar_html, unsafe_allow_html=True)
|
| 1212 |
|
| 1213 |
# Navigation
|
| 1214 |
page = st.radio(
|
|
@@ -1257,7 +1166,7 @@ elif page == "βΉοΈ About":
|
|
| 1257 |
render_about_page()
|
| 1258 |
|
| 1259 |
# Footer
|
| 1260 |
-
|
| 1261 |
<div class="footer-enhanced">
|
| 1262 |
<div class="footer-features">
|
| 1263 |
<div class="footer-feature">
|
|
@@ -1284,6 +1193,4 @@ footer_html = """
|
|
| 1284 |
Powered by Advanced AI β’ Making Truth Accessible to Everyone
|
| 1285 |
</div>
|
| 1286 |
</div>
|
| 1287 |
-
"""
|
| 1288 |
-
|
| 1289 |
-
st.markdown(footer_html, unsafe_allow_html=True)
|
|
|
|
| 1 |
+
# Fix HuggingFace cache permissions - MUST BE AT TOP
|
| 2 |
+
import os
|
| 3 |
+
import tempfile
|
| 4 |
+
|
| 5 |
+
# Set writable cache directories
|
| 6 |
+
temp_dir = tempfile.gettempdir()
|
| 7 |
+
os.environ['HF_HOME'] = temp_dir
|
| 8 |
+
os.environ['TRANSFORMERS_CACHE'] = temp_dir
|
| 9 |
+
os.environ['HF_HUB_CACHE'] = temp_dir
|
| 10 |
+
|
| 11 |
import streamlit as st
|
| 12 |
import torch
|
| 13 |
from transformers import pipeline
|
|
|
|
| 16 |
import time
|
| 17 |
import requests
|
| 18 |
from bs4 import BeautifulSoup
|
|
|
|
| 19 |
import json
|
| 20 |
import re
|
| 21 |
from datetime import datetime
|
|
|
|
| 26 |
GENAI_AVAILABLE = True
|
| 27 |
except ImportError:
|
| 28 |
GENAI_AVAILABLE = False
|
|
|
|
| 29 |
|
| 30 |
# ==============================================================================
|
| 31 |
# π¨ STREAMLIT CONFIGURATION
|
|
|
|
| 48 |
API_CONFIGURED = True
|
| 49 |
except Exception as e:
|
| 50 |
API_CONFIGURED = False
|
|
|
|
| 51 |
else:
|
| 52 |
API_CONFIGURED = False
|
| 53 |
|
|
|
|
| 296 |
border-right: 1px solid rgba(99, 102, 241, 0.2) !important;
|
| 297 |
}
|
| 298 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
.footer-enhanced {
|
| 300 |
text-align: center;
|
| 301 |
padding: 2rem;
|
|
|
|
| 393 |
|
| 394 |
@st.cache_resource(show_spinner=False)
|
| 395 |
def load_ai_models():
|
| 396 |
+
"""Load and cache AI models with enhanced error handling"""
|
| 397 |
try:
|
| 398 |
with st.spinner("π§ Loading AI models..."):
|
| 399 |
+
# Load models with CPU device and custom cache
|
| 400 |
classifier_b1 = pipeline(
|
| 401 |
"text-classification",
|
| 402 |
model=BRAIN_1_MODEL,
|
| 403 |
return_all_scores=True,
|
| 404 |
+
device=-1,
|
| 405 |
+
cache_dir=temp_dir,
|
| 406 |
model_kwargs={"torch_dtype": torch.float32}
|
| 407 |
)
|
| 408 |
classifier_b2 = pipeline(
|
| 409 |
"text-classification",
|
| 410 |
model=BRAIN_2_MODEL,
|
| 411 |
+
device=-1,
|
| 412 |
+
cache_dir=temp_dir,
|
| 413 |
model_kwargs={"torch_dtype": torch.float32}
|
| 414 |
)
|
| 415 |
return classifier_b1, classifier_b2
|
| 416 |
+
|
| 417 |
except Exception as e:
|
| 418 |
st.error(f"π΄ Model loading failed: {str(e)}")
|
| 419 |
return None, None
|
|
|
|
| 523 |
return f"Analysis complete: {brain_2_result['label']} verdict with {brain_2_result['score']:.1%} confidence. Primary nuance: {b1_top['label'].replace('-', ' ').title()}."
|
| 524 |
|
| 525 |
# ==============================================================================
|
| 526 |
+
# π¨ UI COMPONENTS - FIXED HTML RENDERING
|
| 527 |
# ==============================================================================
|
| 528 |
def render_hero_section():
|
| 529 |
"""Render the hero section"""
|
| 530 |
+
st.markdown("""
|
| 531 |
<div class="hero-container">
|
| 532 |
<h1 class="main-title">π§ Credo AI Platform</h1>
|
| 533 |
<p class="hero-subtitle">
|
|
|
|
| 550 |
</div>
|
| 551 |
</div>
|
| 552 |
</div>
|
| 553 |
+
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 554 |
|
| 555 |
def render_analysis_results(results):
|
| 556 |
"""Render analysis results with enhanced styling"""
|
| 557 |
# AI Summary
|
| 558 |
st.markdown("### β¨ AI-Powered Analysis Summary")
|
| 559 |
|
| 560 |
+
st.markdown(f"""
|
| 561 |
<div class="summary-box">
|
| 562 |
{results['summary']}
|
| 563 |
</div>
|
| 564 |
+
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
| 565 |
|
| 566 |
# Results columns
|
| 567 |
col1, col2 = st.columns(2, gap="large")
|
|
|
|
| 573 |
|
| 574 |
verdict_class = 'verdict-fake' if verdict == 'FAKE' else 'verdict-real'
|
| 575 |
|
| 576 |
+
st.markdown(f"""
|
| 577 |
<div class="verdict-container {verdict_class}">
|
| 578 |
<div class="verdict-text">{verdict}</div>
|
| 579 |
</div>
|
| 580 |
<div style="text-align: center; margin-top: 1rem; font-size: 1.5rem; font-weight: 600; color: #f1f5f9;">
|
| 581 |
{confidence:.1%} Confidence
|
| 582 |
</div>
|
| 583 |
+
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
| 584 |
|
| 585 |
with col2:
|
| 586 |
st.markdown("### π§ Nuance Analysis")
|
|
|
|
| 637 |
classifier_b1, classifier_b2 = load_ai_models()
|
| 638 |
|
| 639 |
if not classifier_b1 or not classifier_b2:
|
| 640 |
+
st.error("π΄ Failed to load AI models. Please try again or check your internet connection.")
|
| 641 |
return
|
| 642 |
|
| 643 |
text_to_analyze = user_input
|
|
|
|
| 663 |
st.write(f"β
Successfully extracted {metadata['word_count']} words")
|
| 664 |
|
| 665 |
if metadata['word_count'] < 50:
|
| 666 |
+
st.warning("β οΈ Very short content extracted. Results may be less reliable.")
|
| 667 |
else:
|
| 668 |
+
st.error(f"β Failed to fetch content: {web_data['error']}")
|
| 669 |
return
|
| 670 |
else:
|
| 671 |
metadata['word_count'] = len(text_to_analyze.split())
|
|
|
|
| 678 |
|
| 679 |
# Validate minimum content
|
| 680 |
if len(text_to_analyze.strip()) < 10:
|
| 681 |
+
st.warning("β οΈ Content too short for meaningful analysis. Please provide more text.")
|
| 682 |
return
|
| 683 |
|
| 684 |
# AI Analysis
|
|
|
|
| 701 |
status.update(label="β
Analysis complete!", state="complete")
|
| 702 |
|
| 703 |
except Exception as e:
|
| 704 |
+
st.error(f"β Analysis failed: {str(e)}")
|
| 705 |
return
|
| 706 |
|
| 707 |
# Store results
|
|
|
|
| 813 |
# Input validation and processing
|
| 814 |
if analyze_btn:
|
| 815 |
if not user_input.strip():
|
| 816 |
+
st.warning("β οΈ Please provide some content to analyze.")
|
| 817 |
elif len(user_input.strip()) < 10:
|
| 818 |
+
st.warning("β οΈ Please provide more content for meaningful analysis (minimum 10 characters).")
|
| 819 |
elif input_method == "URL/Website" and not user_input.startswith(('http://', 'https://')):
|
| 820 |
+
st.warning("β οΈ Please enter a valid URL starting with http:// or https://")
|
| 821 |
else:
|
| 822 |
process_analysis(user_input, input_method)
|
| 823 |
|
|
|
|
| 858 |
mime="application/json"
|
| 859 |
)
|
| 860 |
|
| 861 |
+
st.success("π Analysis report ready for download!")
|
| 862 |
|
| 863 |
# ==============================================================================
|
| 864 |
+
# π― PAGE RENDERERS - FIXED NOTIFICATIONS
|
| 865 |
# ==============================================================================
|
| 866 |
def render_live_analysis_page():
|
| 867 |
"""Main analysis page"""
|
|
|
|
| 875 |
|
| 876 |
# Show API status
|
| 877 |
if not API_CONFIGURED:
|
| 878 |
+
st.warning("π **Setup Required:** Add your Google API key in Space Settings β Variables and Secrets β Add: GOOGLE_API_KEY. The platform will work with basic summaries until the API key is configured.")
|
|
|
|
|
|
|
|
|
|
| 879 |
|
| 880 |
# Analysis interface
|
| 881 |
render_analysis_interface()
|
|
|
|
| 891 |
st.markdown("# π Analysis History")
|
| 892 |
|
| 893 |
if 'analysis_history' not in st.session_state or not st.session_state.analysis_history:
|
| 894 |
+
st.info("π **No Analysis History** - Your analysis history will appear here after you perform some fact-checking analyses. Start by going to the Live Analysis page and analyzing some content!")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 895 |
return
|
| 896 |
|
| 897 |
history = st.session_state.analysis_history
|
|
|
|
| 984 |
"""About page with system information"""
|
| 985 |
st.markdown("# π¬ About Credo AI")
|
| 986 |
|
| 987 |
+
st.markdown("""
|
| 988 |
<div class="glass-card">
|
| 989 |
<h2 style="color: #6366f1; margin-bottom: 1rem;">π Revolutionary Detection Technology</h2>
|
| 990 |
<p style="font-size: 1.2rem; color: #cbd5e1; line-height: 1.7;">
|
|
|
|
| 993 |
to deliver unparalleled accuracy in misinformation detection.
|
| 994 |
</p>
|
| 995 |
</div>
|
| 996 |
+
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
| 997 |
|
| 998 |
# Technical details in tabs
|
| 999 |
tab1, tab2, tab3, tab4 = st.tabs(["π§ AI Architecture", "π Performance", "π¬ Technology", "π οΈ System Status"])
|
|
|
|
| 1035 |
df = pd.DataFrame(metrics_data)
|
| 1036 |
st.dataframe(df, use_container_width=True, hide_index=True)
|
| 1037 |
|
| 1038 |
+
st.success("π **Industry Leading:** Credo AI consistently outperforms single-model approaches by 15-25% across major misinformation datasets.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1039 |
|
| 1040 |
with tab3:
|
| 1041 |
st.markdown("""
|
|
|
|
| 1058 |
**β‘ Performance & Optimization:**
|
| 1059 |
- Intelligent caching system
|
| 1060 |
- Memory-efficient processing
|
|
|
|
| 1061 |
- Progressive loading
|
| 1062 |
- Mobile-responsive design
|
| 1063 |
|
|
|
|
| 1066 |
- Secure API key management
|
| 1067 |
- Privacy-first architecture
|
| 1068 |
- Local processing where possible
|
|
|
|
| 1069 |
""")
|
| 1070 |
|
| 1071 |
with tab4:
|
|
|
|
| 1081 |
# Model availability
|
| 1082 |
try:
|
| 1083 |
load_ai_models()
|
| 1084 |
+
model_status = "π’ Ready"
|
| 1085 |
except:
|
| 1086 |
+
model_status = "π΄ Loading"
|
| 1087 |
status_data.append(["AI Models", model_status])
|
| 1088 |
|
| 1089 |
# Memory usage
|
|
|
|
| 1101 |
status_df = pd.DataFrame(status_data, columns=['Component', 'Status'])
|
| 1102 |
st.dataframe(status_df, use_container_width=True, hide_index=True)
|
| 1103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1104 |
# ==============================================================================
|
| 1105 |
# π MAIN APPLICATION
|
| 1106 |
# ==============================================================================
|
|
|
|
| 1112 |
# Sidebar navigation
|
| 1113 |
with st.sidebar:
|
| 1114 |
# Sidebar header
|
| 1115 |
+
st.markdown("""
|
| 1116 |
<div style="text-align: center; padding: 1rem 0; margin-bottom: 2rem;">
|
| 1117 |
<h2 style="color: #6366f1; margin: 0;">π§ Credo AI</h2>
|
| 1118 |
<p style="color: #94a3b8; margin: 0.5rem 0 0 0; font-size: 0.9rem;">Truth Detection Platform</p>
|
| 1119 |
</div>
|
| 1120 |
+
""", unsafe_allow_html=True)
|
|
|
|
|
|
|
| 1121 |
|
| 1122 |
# Navigation
|
| 1123 |
page = st.radio(
|
|
|
|
| 1166 |
render_about_page()
|
| 1167 |
|
| 1168 |
# Footer
|
| 1169 |
+
st.markdown("""
|
| 1170 |
<div class="footer-enhanced">
|
| 1171 |
<div class="footer-features">
|
| 1172 |
<div class="footer-feature">
|
|
|
|
| 1193 |
Powered by Advanced AI β’ Making Truth Accessible to Everyone
|
| 1194 |
</div>
|
| 1195 |
</div>
|
| 1196 |
+
""", unsafe_allow_html=True)
|
|
|
|
|
|