""" RICA Agent - Complete Fixed Version """ import streamlit as st import os import sys from pathlib import Path import json # Add project root to path for imports if str(Path(__file__).parent) not in sys.path: sys.path.append(str(Path(__file__).parent)) # Import modules 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() # Initialize session state 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 # Page configuration st.set_page_config( page_title="RICA - AI Revenue Intelligence", page_icon="🤖", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS st.markdown(""" """, unsafe_allow_html=True) # Header st.markdown('

🤖 RICA - AI Revenue Intelligence Agent

', unsafe_allow_html=True) st.markdown("### Enterprise Business Intelligence Powered by Machine Learning") # Sidebar configuration with st.sidebar: st.header("🔧 Configuration") # API Key input with proper validation openai_key = st.text_input( "OpenAI API Key", type="password", help="Required for AI agent operations", key="openai_api_key", placeholder="sk-..." ) # Validate and store API key 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() # Model status 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() # Analysis configuration (only if API key is valid) 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 # Advanced options 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 # Main content logic if not st.session_state.api_key_valid: # Show welcome screen when API key not configured 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 """) # Demo metrics 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: # Model training required 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: # Main analysis interface - API key valid and model trained st.markdown("## 🎯 AI Business Intelligence Dashboard") # Analysis execution if st.button("🚀 Run RICA Analysis", type="primary", use_container_width=True): with st.spinner("🤖 RICA is analyzing your business data..."): try: # Execute analysis 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) # Display results st.success("✅ Analysis Complete!") # Create tabs for different result views 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)) # Raw response in expander 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") # Show model performance metrics 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") # Footer st.markdown("---") st.markdown("🤖 **RICA Agent** | ML + AI for Business Intelligence | Deployed on 🤗 Hugging Face Spaces")