File size: 11,064 Bytes
b7b1f98
e7df474
b7b1f98
 
 
 
 
e7df474
 
b7b1f98
 
 
 
 
 
e7df474
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7b1f98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e7df474
b7b1f98
 
e7df474
 
 
 
b7b1f98
 
e7df474
 
b7b1f98
e7df474
 
 
 
 
 
 
b7b1f98
e7df474
b7b1f98
 
 
 
 
 
 
e7df474
 
b7b1f98
 
 
e7df474
 
 
 
 
 
 
 
 
b7b1f98
 
e7df474
b7b1f98
e7df474
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7b1f98
 
 
e7df474
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7b1f98
e7df474
 
 
b7b1f98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e7df474
b7b1f98
 
 
 
 
 
 
 
 
 
 
 
 
 
e7df474
 
b7b1f98
 
 
e7df474
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7b1f98
e7df474
 
b7b1f98
 
e7df474
 
 
b7b1f98
e7df474
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b7b1f98
e7df474
b7b1f98
 
e7df474
 
 
 
 
 
 
 
 
 
 
 
 
b7b1f98
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
"""
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("""
<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)

# Header
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")

# 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")