|
""" |
|
RICA Agent - Complete Fixed Version |
|
""" |
|
|
|
import streamlit as st |
|
import os |
|
import sys |
|
from pathlib import Path |
|
import json |
|
|
|
|
|
if str(Path(__file__).parent) not in sys.path: |
|
sys.path.append(str(Path(__file__).parent)) |
|
|
|
|
|
try: |
|
from utils.model_trainer import EmbeddedChurnTrainer |
|
from agent.rica_agent import execute_rica_analysis_hf |
|
except ImportError as e: |
|
st.error(f"Import error: {e}") |
|
st.stop() |
|
|
|
|
|
if 'api_key_valid' not in st.session_state: |
|
st.session_state.api_key_valid = False |
|
if 'model_trained' not in st.session_state: |
|
st.session_state.model_trained = False |
|
if 'trainer' not in st.session_state: |
|
st.session_state.trainer = EmbeddedChurnTrainer() |
|
if 'analysis_type' not in st.session_state: |
|
st.session_state.analysis_type = 'comprehensive' |
|
if 'risk_threshold' not in st.session_state: |
|
st.session_state.risk_threshold = 0.6 |
|
if 'max_customers' not in st.session_state: |
|
st.session_state.max_customers = 200 |
|
|
|
|
|
st.set_page_config( |
|
page_title="RICA - AI Revenue Intelligence", |
|
page_icon="π€", |
|
layout="wide", |
|
initial_sidebar_state="expanded" |
|
) |
|
|
|
|
|
st.markdown(""" |
|
<style> |
|
.main-header { |
|
font-size: 2.5rem; |
|
font-weight: bold; |
|
text-align: center; |
|
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); |
|
-webkit-background-clip: text; |
|
-webkit-text-fill-color: transparent; |
|
margin-bottom: 1rem; |
|
} |
|
.stAlert > div { |
|
padding: 0.5rem; |
|
} |
|
.metric-container { |
|
background: #f0f2f6; |
|
padding: 1rem; |
|
border-radius: 0.5rem; |
|
margin: 0.5rem 0; |
|
} |
|
</style> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown('<h1 class="main-header">π€ RICA - AI Revenue Intelligence Agent</h1>', unsafe_allow_html=True) |
|
st.markdown("### Enterprise Business Intelligence Powered by Machine Learning") |
|
|
|
|
|
with st.sidebar: |
|
st.header("π§ Configuration") |
|
|
|
|
|
openai_key = st.text_input( |
|
"OpenAI API Key", |
|
type="password", |
|
help="Required for AI agent operations", |
|
key="openai_api_key", |
|
placeholder="sk-..." |
|
) |
|
|
|
|
|
if openai_key and openai_key.startswith('sk-') and len(openai_key) > 20: |
|
os.environ["OPENAI_API_KEY"] = openai_key |
|
st.session_state.api_key_valid = True |
|
st.success("β
OpenAI API Key Configured") |
|
st.caption("Key validated and ready for use") |
|
elif openai_key: |
|
st.session_state.api_key_valid = False |
|
st.error("β Invalid API Key Format") |
|
st.caption("Key should start with 'sk-' and be longer than 20 characters") |
|
else: |
|
st.session_state.api_key_valid = False |
|
st.warning("β οΈ Enter API Key to enable AI features") |
|
|
|
st.divider() |
|
|
|
|
|
st.header("π§ ML Model Status") |
|
|
|
trainer = st.session_state.trainer |
|
model_exists = trainer.model_exists() |
|
|
|
if model_exists: |
|
st.success("β
Model Ready") |
|
try: |
|
metadata = trainer.load_existing_metadata() |
|
if metadata and 'metrics' in metadata: |
|
st.metric("Model Accuracy", f"{metadata['metrics'].get('test_accuracy', 0):.1%}") |
|
st.metric("Training Date", metadata.get('training_date', 'Unknown')[:10]) |
|
st.session_state.model_trained = True |
|
except: |
|
st.info("Model exists but metadata unavailable") |
|
st.session_state.model_trained = True |
|
else: |
|
st.warning("β οΈ Model Not Trained") |
|
st.session_state.model_trained = False |
|
|
|
if st.button("ποΈ Train Model Now", type="primary", key="train_model_btn"): |
|
if not st.session_state.api_key_valid: |
|
st.error("Please configure API key first") |
|
else: |
|
with st.spinner("Training ML model... This may take 1-2 minutes"): |
|
try: |
|
metrics = trainer.train_model_if_needed() |
|
if metrics: |
|
st.success("π Model trained successfully!") |
|
st.session_state.model_trained = True |
|
st.rerun() |
|
else: |
|
st.error("Training failed. Please check the logs.") |
|
except Exception as e: |
|
st.error(f"Training error: {str(e)}") |
|
|
|
st.divider() |
|
|
|
|
|
if st.session_state.api_key_valid: |
|
st.header("π Analysis Options") |
|
|
|
analysis_type = st.selectbox( |
|
"Select Analysis Type", |
|
["comprehensive", "churn_focus", "quick_insights"], |
|
format_func=lambda x: { |
|
"comprehensive": "π― Comprehensive Review", |
|
"churn_focus": "π¨ Churn Risk Analysis", |
|
"quick_insights": "β‘ Quick Insights" |
|
}[x], |
|
key="analysis_type_select" |
|
) |
|
|
|
st.session_state.analysis_type = analysis_type |
|
|
|
|
|
with st.expander("βοΈ Advanced Options"): |
|
risk_threshold = st.slider( |
|
"Churn Risk Threshold", |
|
0.3, 0.9, 0.6, |
|
key="risk_threshold_slider" |
|
) |
|
max_customers = st.number_input( |
|
"Max Customers to Analyze", |
|
50, 500, 200, |
|
key="max_customers_input" |
|
) |
|
|
|
st.session_state.risk_threshold = risk_threshold |
|
st.session_state.max_customers = max_customers |
|
|
|
|
|
if not st.session_state.api_key_valid: |
|
|
|
st.info("π Please enter your OpenAI API Key in the sidebar to begin") |
|
|
|
col1, col2 = st.columns(2) |
|
|
|
with col1: |
|
st.markdown(""" |
|
## π Capabilities |
|
|
|
**RICA** combines machine learning with autonomous AI to deliver: |
|
|
|
- π― **Churn Prediction**: ML models identify at-risk customers |
|
- π **Real-time Analysis**: Direct SAP data integration |
|
- π€ **Autonomous Insights**: LLM-powered recommendations |
|
- π **Business Impact**: Actionable revenue optimization |
|
""") |
|
|
|
with col2: |
|
st.markdown(""" |
|
## ποΈ Architecture |
|
|
|
- **Data Source**: Real SAP/SALT dataset |
|
- **ML Engine**: Scikit-learn Random Forest |
|
- **Agent Framework**: smolagents + OpenAI |
|
- **Analytics**: DuckDB high-performance processing |
|
- **UI**: Streamlit interactive interface |
|
""") |
|
|
|
|
|
st.markdown("## π Sample Analytics Preview") |
|
|
|
col1, col2, col3, col4 = st.columns(4) |
|
|
|
with col1: |
|
st.metric("Customers", "2,847", delta="12%") |
|
with col2: |
|
st.metric("Churn Risk", "23 customers", delta="-8", delta_color="inverse") |
|
with col3: |
|
st.metric("Revenue at Risk", "$1.2M", delta="15%") |
|
with col4: |
|
st.metric("Model Accuracy", "87.3%", delta="2.1%") |
|
|
|
elif not st.session_state.model_trained: |
|
|
|
st.warning("π§ Machine learning model needs to be trained before analysis") |
|
st.info("π Use the 'Train Model Now' button in the sidebar (takes 1-2 minutes)") |
|
|
|
st.markdown("## π Training Process") |
|
st.markdown(""" |
|
1. **Load SAP Data**: Customer and sales data from Hugging Face Hub |
|
2. **Feature Engineering**: RFM analysis and behavioral patterns |
|
3. **Model Training**: Random Forest classifier with cross-validation |
|
4. **Performance Validation**: Accuracy testing and metrics calculation |
|
5. **Model Persistence**: Save for future predictions |
|
""") |
|
|
|
else: |
|
|
|
st.markdown("## π― AI Business Intelligence Dashboard") |
|
|
|
|
|
if st.button("π Run RICA Analysis", type="primary", use_container_width=True): |
|
with st.spinner("π€ RICA is analyzing your business data..."): |
|
try: |
|
|
|
parameters = { |
|
"risk_threshold": st.session_state.risk_threshold, |
|
"max_customers": st.session_state.max_customers |
|
} |
|
|
|
result = execute_rica_analysis_hf(st.session_state.analysis_type, parameters) |
|
|
|
|
|
st.success("β
Analysis Complete!") |
|
|
|
|
|
if st.session_state.analysis_type == "comprehensive": |
|
tab1, tab2, tab3 = st.tabs(["π Executive Summary", "π¨ Risk Analysis", "π‘ Recommendations"]) |
|
|
|
with tab1: |
|
st.markdown("### Executive Dashboard") |
|
st.info(str(result)) |
|
|
|
with tab2: |
|
st.markdown("### Customer Risk Analysis") |
|
st.write("Detailed churn risk breakdown and customer segmentation") |
|
|
|
with tab3: |
|
st.markdown("### AI Recommendations") |
|
st.write("Specific actions prioritized by business impact") |
|
|
|
else: |
|
st.markdown(f"### {st.session_state.analysis_type.replace('_', ' ').title()} Results") |
|
st.info(str(result)) |
|
|
|
|
|
with st.expander("π Detailed Analysis Response"): |
|
st.code(str(result), language="text") |
|
|
|
except Exception as e: |
|
st.error(f"β Analysis failed: {str(e)}") |
|
st.info("Please check your API key and model status") |
|
|
|
|
|
if st.session_state.trainer.model_exists(): |
|
st.markdown("## π Model Performance") |
|
try: |
|
metadata = st.session_state.trainer.load_existing_metadata() |
|
if metadata and 'metrics' in metadata: |
|
col1, col2, col3 = st.columns(3) |
|
|
|
with col1: |
|
st.metric("Model Accuracy", f"{metadata['metrics'].get('test_accuracy', 0):.1%}") |
|
with col2: |
|
st.metric("Training Samples", f"{metadata['metrics'].get('training_samples', 0):,}") |
|
with col3: |
|
st.metric("Churn Rate", f"{metadata['metrics'].get('churn_rate', 0):.1%}") |
|
except: |
|
st.info("Model performance metrics unavailable") |
|
|
|
|
|
st.markdown("---") |
|
st.markdown("π€ **RICA Agent** | ML + AI for Business Intelligence | Deployed on π€ Hugging Face Spaces") |
|
|