Rahul2298 commited on
Commit
dd92cd2
·
verified ·
1 Parent(s): 03c17ff

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +554 -48
src/streamlit_app.py CHANGED
@@ -1,50 +1,556 @@
1
- # Add a FINANCE_KEYWORDS list at the top
2
- FINANCE_KEYWORDS = [
3
- "finance", "money", "budget", "spend", "expense", "investment", "invest",
4
- "mutual fund", "savings", "loan", "credit", "debit", "stock", "tax",
5
- "insurance", "emi", "pay", "salary", "income", "expense", "roi",
6
- "interest", "dividend", "bond", "rate", "portfolio", "wealth", "goal",
7
- "sip", "fd", "rd", "fixed deposit", "asset", "liability", "capital"
8
- ]
9
-
10
- def is_finance_related(text):
11
- text_l = text.lower()
12
- # Keywords
13
- if any(word in text_l for word in FINANCE_KEYWORDS):
14
- return True
15
- # Numbers (strip commas, dots, %)
16
- if any(char.isdigit() for char in text):
17
- return True
18
- return False
19
-
20
- # In your chat input section, filter before sending to the AI
21
- with col_chat:
22
- st.subheader("🗣️ Ask about finance or numbers only")
23
- for turn in st.session_state.chat_history:
24
- with st.chat_message(turn["role"]):
25
- st.markdown(turn["content"])
26
- user_msg = st.chat_input("Type your finance/numbers-related question…")
27
- if user_msg:
28
- if not is_finance_related(user_msg):
29
- assistant_message = "Sorry, I can only answer questions related to finance or numbers. Please rephrase your query."
30
- st.session_state.chat_history.append({"role": "assistant", "content": assistant_message})
31
- with st.chat_message("assistant"):
32
- st.markdown(assistant_message)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  else:
34
- st.session_state.chat_history.append({"role": "user", "content": user_msg})
35
- intent = detect_intent(user_msg)
36
- sys_prompt = (
37
- "You are a finance and numbers-only AI assistant. "
38
- "If asked anything outside of finance or numbers, politely refuse to answer."
39
- "\n\n" + build_system_prompt(profile)
 
 
 
 
 
 
 
 
 
 
 
40
  )
41
- usr_prompt = craft_user_prompt(user_msg, intent, summary)
42
- final_prompt = sys_prompt + "\n\n" + usr_prompt
43
- with st.chat_message("assistant"):
44
- with st.spinner(f"Thinking with {provider.name}…"):
45
- try:
46
- ai = provider.generate(final_prompt, max_tokens=768)
47
- except Exception as e:
48
- ai = f"Provider error: {e}\nFalling back to heuristic guidance.\n" + usr_prompt
49
- st.markdown(ai)
50
- st.session_state.chat_history.append({"role": "assistant", "content": ai})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Personal Finance Chatbot: AI-Powered Financial Advisor
2
+ # Enhanced with OpenAI GPT for superior accuracy and intelligence
3
+
4
+ import os
5
+ import io
6
+ import re
7
+ import json
8
+ from dataclasses import dataclass
9
+ from typing import List, Dict, Optional, Any, Union
10
+
11
+ import pandas as pd
12
+ import streamlit as st
13
+
14
+ # OpenAI Integration
15
+ try:
16
+ from openai import OpenAI
17
+ OPENAI_AVAILABLE = True
18
+ except ImportError:
19
+ OPENAI_AVAILABLE = False
20
+
21
+ # HuggingFace Fallback
22
+ try:
23
+ from transformers import pipeline
24
+ HF_AVAILABLE = True
25
+ HF_PIPELINE = pipeline
26
+ except ImportError:
27
+ HF_AVAILABLE = False
28
+ HF_PIPELINE = None
29
+
30
+ st.set_page_config(
31
+ page_title="FinanceAI - Smart Financial Advisor",
32
+ page_icon="🤖",
33
+ layout="wide",
34
+ initial_sidebar_state="collapsed"
35
+ )
36
+
37
+ if "chat_history" not in st.session_state:
38
+ st.session_state.chat_history = []
39
+ if "provider_inited" not in st.session_state:
40
+ st.session_state.provider_inited = False
41
+ if "provider_name" not in st.session_state:
42
+ st.session_state.provider_name = "openai"
43
+
44
+ class AIProvider:
45
+ def __init__(self):
46
+ self.name = "base"
47
+ def generate(self, prompt: str, max_tokens: int = 512) -> str:
48
+ raise NotImplementedError
49
+
50
+ class OpenAIProvider(AIProvider):
51
+ def __init__(self):
52
+ super().__init__()
53
+ self.name = "OpenAI GPT-4"
54
+ self.client = None
55
+ api_key = os.environ.get("OPENAI_API_KEY")
56
+ if OPENAI_AVAILABLE and api_key:
57
+ try:
58
+ self.client = OpenAI(api_key=api_key)
59
+ # Test the connection
60
+ self.client.models.list()
61
+ self.available = True
62
+ except Exception as e:
63
+ st.warning(f"OpenAI connection failed: {e}")
64
+ self.available = False
65
+ self.client = None
66
  else:
67
+ self.available = False
68
+
69
+ def generate(self, prompt: str, max_tokens: int = 768) -> str:
70
+ if not self.available or not self.client:
71
+ return "OpenAI service unavailable. Please check your API key."
72
+
73
+ try:
74
+ # Use GPT-4 for superior financial advice
75
+ response = self.client.chat.completions.create(
76
+ model="gpt-4o-mini", # Using the latest efficient model
77
+ messages=[
78
+ {"role": "system", "content": "You are FinanceAI, a highly knowledgeable financial advisor specializing in Indian markets, tax laws, and investment strategies. Provide accurate, actionable advice with specific amounts and calculations."},
79
+ {"role": "user", "content": prompt}
80
+ ],
81
+ max_tokens=max_tokens,
82
+ temperature=0.7,
83
+ top_p=0.9
84
  )
85
+ return response.choices[0].message.content.strip()
86
+ except Exception as e:
87
+ return f"Error generating response: {str(e)}"
88
+
89
+ class HuggingFaceProvider(AIProvider):
90
+ def __init__(self):
91
+ super().__init__()
92
+ self.name = "HuggingFace Fallback"
93
+ self.gen = None
94
+ if HF_AVAILABLE and HF_PIPELINE:
95
+ try:
96
+ self.gen = HF_PIPELINE("text2text-generation", model="google/flan-t5-base")
97
+ self.available = True
98
+ except Exception as e:
99
+ st.warning(f"HuggingFace pipeline failed to load: {e}")
100
+ self.available = False
101
+ else:
102
+ self.available = False
103
+
104
+ def generate(self, prompt: str, max_tokens: int = 512) -> str:
105
+ if not self.available or self.gen is None:
106
+ return self._fallback_response(prompt)
107
+
108
+ try:
109
+ out = self.gen(prompt, max_length=min(1024, max_tokens), do_sample=False)
110
+ return out[0]["generated_text"].strip()
111
+ except Exception:
112
+ return self._fallback_response(prompt)
113
+
114
+ def _fallback_response(self, prompt: str) -> str:
115
+ return (
116
+ "🤖 **AI-Enhanced Financial Guidance**\n\n"
117
+ "Based on your query, here are key recommendations:\n"
118
+ "• **Emergency Fund**: Build 6 months of expenses in liquid funds\n"
119
+ "• **Tax Saving**: Utilize Section 80C (₹1.5L limit) through ELSS/PPF\n"
120
+ "• **Investment**: Balance equity (60%) and debt (40%) based on risk profile\n"
121
+ "• **Insurance**: Term life insurance of 10x annual income\n\n"
122
+ "For personalized calculations, please provide your monthly income and goals."
123
+ )
124
+
125
+ CATEGORIES = {
126
+ "groceries": ["grocery", "supermarket", "food", "mart", "vegetables", "fruits"],
127
+ "rent": ["rent", "landlord", "housing"],
128
+ "utilities": ["electric", "water", "gas", "utility", "internet", "mobile", "phone"],
129
+ "transport": ["uber", "ola", "fuel", "bus", "metro", "train", "cab", "petrol", "diesel"],
130
+ "entertainment": ["netflix", "spotify", "movie", "cinema", "concert", "game", "youtube"],
131
+ "health": ["pharmacy", "doctor", "hospital", "clinic", "medicine", "health"],
132
+ "eating_out": ["restaurant", "cafe", "bar", "eatery", "diner", "zomato", "swiggy"],
133
+ "shopping": ["amazon", "flipkart", "myntra", "shop", "store", "clothing"],
134
+ "income": ["salary", "stipend", "bonus", "interest", "dividend", "freelance"],
135
+ "investment": ["sip", "mutual fund", "stock", "gold", "ppf", "fd"],
136
+ "insurance": ["insurance", "premium", "policy"],
137
+ "education": ["fees", "books", "course", "training"],
138
+ "travel": ["flight", "hotel", "vacation", "trip"]
139
+ }
140
+
141
+ def categorize(desc: str) -> str:
142
+ desc_l = (desc or "").lower()
143
+ for cat, keys in CATEGORIES.items():
144
+ if any(k in desc_l for k in keys):
145
+ return cat
146
+ return "other"
147
+
148
+ @dataclass
149
+ class UserProfile:
150
+ name: str
151
+ user_type: str
152
+ age: int
153
+ country: str
154
+ monthly_income: float
155
+ risk_tolerance: str
156
+ goals: str
157
+
158
+ def get_risk_level(self) -> str:
159
+ risk_map = {
160
+ "conservative": "low",
161
+ "moderate": "medium",
162
+ "aggressive": "high"
163
+ }
164
+ return risk_map.get(self.risk_tolerance.lower(), "medium")
165
+
166
+ def load_transactions(uploaded_file: Optional[io.BytesIO]) -> pd.DataFrame:
167
+ if uploaded_file is None:
168
+ # Enhanced sample data with more realistic transactions
169
+ data = {
170
+ "date": pd.date_range("2025-01-01", periods=30, freq="D"),
171
+ "description": [
172
+ "Salary Credit", "Rent Payment", "Grocery Store", "Restaurant Bill", "Metro Card",
173
+ "Internet Bill", "Pharmacy", "Movie Ticket", "Amazon Purchase", "Fuel Station",
174
+ "Bonus Credit", "Electricity Bill", "Coffee Shop", "Supermarket", "Hospital",
175
+ "Netflix Subscription", "Uber Ride", "Water Bill", "Gym Membership", "Flipkart",
176
+ "Bus Pass", "Medicine", "Dividend Credit", "Train Ticket", "SIP Investment",
177
+ "Insurance Premium", "Mobile Recharge", "Zomato Order", "Book Purchase", "ATM Withdrawal"
178
+ ],
179
+ "amount": [
180
+ 75000, -18000, -3200, -1200, -500, -1500, -800, -400, -2800, -2000,
181
+ 15000, -2200, -300, -2800, -3500, -800, -250, -600, -2000, -1500,
182
+ -400, -450, 2500, -180, -5000, -3000, -399, -850, -550, -2000
183
+ ],
184
+ }
185
+ df = pd.DataFrame(data)
186
+ else:
187
+ df = pd.read_csv(uploaded_file)
188
+
189
+ df["category"] = df["description"].apply(categorize)
190
+ return df
191
+
192
+ def budget_summary(df: pd.DataFrame, monthly_income_hint: Optional[float] = None) -> Dict[str, Union[float, str]]:
193
+ try:
194
+ df["month"] = pd.to_datetime(df["date"]).dt.to_period("M").astype(str)
195
+ income = df.loc[df["amount"] > 0, "amount"].sum()
196
+ expenses = -df.loc[df["amount"] < 0, "amount"].sum()
197
+ net = income - expenses
198
+
199
+ if monthly_income_hint and monthly_income_hint > 0:
200
+ income = max(income, monthly_income_hint)
201
+ net = income - expenses
202
+
203
+ savings_rate = (net / income) * 100 if income > 0 else 0.0
204
+
205
+ # Category breakdown
206
+ expense_by_category = df[df["amount"] < 0].groupby("category")["amount"].sum().abs()
207
+ top_expenses = expense_by_category.nlargest(5)
208
+
209
+ return {
210
+ "income_total": float(round(income, 2)),
211
+ "expense_total": float(round(expenses, 2)),
212
+ "net_savings": float(round(net, 2)),
213
+ "savings_rate_pct": float(round(savings_rate, 2)),
214
+ "top_expenses": top_expenses.to_dict(),
215
+ "expense_breakdown": expense_by_category.to_dict()
216
+ }
217
+ except Exception as e:
218
+ return {
219
+ "income_total": monthly_income_hint or 50000,
220
+ "expense_total": 35000,
221
+ "net_savings": 15000,
222
+ "savings_rate_pct": 30.0,
223
+ "top_expenses": {},
224
+ "expense_breakdown": {}
225
+ }
226
+
227
+ def generate_ai_financial_plan(profile: UserProfile, summary: Dict[str, Union[float, str]]) -> str:
228
+ """Generate comprehensive AI-powered financial plan"""
229
+
230
+ income = summary["income_total"]
231
+ savings = summary["net_savings"]
232
+ savings_rate = summary["savings_rate_pct"]
233
+
234
+ plan = []
235
+
236
+ # Emergency Fund Strategy
237
+ emergency_fund_target = profile.monthly_income * 6
238
+ monthly_emergency_save = min(profile.monthly_income * 0.15, 10000)
239
+ plan.append(f"🚨 **Emergency Fund Strategy**")
240
+ plan.append(f"Target: ₹{emergency_fund_target:,.0f} (6 months expenses)")
241
+ plan.append(f"Monthly allocation: ₹{monthly_emergency_save:,.0f}")
242
+ plan.append(f"Investment: Liquid funds or high-yield savings (6-8% returns)")
243
+
244
+ # Tax Optimization
245
+ plan.append(f"\n📊 **Tax Optimization Plan**")
246
+ max_80c = 150000
247
+ recommended_80c = min(profile.monthly_income * 12 * 0.125, max_80c)
248
+ monthly_80c = recommended_80c / 12
249
+ plan.append(f"Section 80C: ₹{monthly_80c:,.0f}/month (₹{recommended_80c:,.0f}/year)")
250
+ plan.append(f"Options: ELSS (12-15% returns), PPF (7.1% tax-free), NSC")
251
+
252
+ # Investment Strategy
253
+ plan.append(f"\n🚀 **Investment Allocation Strategy**")
254
+ investable_amount = max(0, savings - monthly_emergency_save)
255
+
256
+ if investable_amount > 1000:
257
+ risk_level = profile.get_risk_level()
258
+ if risk_level == "low":
259
+ equity_pct, debt_pct = 40, 60
260
+ expected_return = "8-10%"
261
+ elif risk_level == "high":
262
+ equity_pct, debt_pct = 80, 20
263
+ expected_return = "12-15%"
264
+ else:
265
+ equity_pct, debt_pct = 60, 40
266
+ expected_return = "10-12%"
267
+
268
+ equity_amount = investable_amount * (equity_pct / 100)
269
+ debt_amount = investable_amount * (debt_pct / 100)
270
+
271
+ plan.append(f"Monthly Investment: ₹{investable_amount:,.0f}")
272
+ plan.append(f"Equity allocation: ₹{equity_amount:,.0f} ({equity_pct}%) - Nifty 50, Large Cap funds")
273
+ plan.append(f"Debt allocation: ₹{debt_amount:,.0f} ({debt_pct}%) - Debt funds, Bonds")
274
+ plan.append(f"Expected annual returns: {expected_return}")
275
+
276
+ # Goal-based Planning
277
+ if "retirement" in profile.goals.lower():
278
+ plan.append(f"\n🏖️ **Retirement Planning**")
279
+ retirement_corpus = profile.monthly_income * 12 * 25
280
+ years_to_retire = 65 - profile.age
281
+ monthly_retirement_sip = retirement_corpus / (years_to_retire * 12) if years_to_retire > 0 else 0
282
+ plan.append(f"Target corpus: ₹{retirement_corpus:,.0f}")
283
+ plan.append(f"Monthly SIP needed: ₹{monthly_retirement_sip:,.0f}")
284
+ plan.append(f"Time horizon: {years_to_retire} years")
285
+
286
+ if any(word in profile.goals.lower() for word in ["house", "home", "property"]):
287
+ plan.append(f"\n🏠 **Home Purchase Plan**")
288
+ home_value = profile.monthly_income * 12 * 5
289
+ down_payment = home_value * 0.2
290
+ years_to_buy = 7
291
+ monthly_home_save = down_payment / (years_to_buy * 12)
292
+ plan.append(f"Target home value: ₹{home_value:,.0f}")
293
+ plan.append(f"Down payment needed: ₹{down_payment:,.0f}")
294
+ plan.append(f"Monthly savings: ₹{monthly_home_save:,.0f} for {years_to_buy} years")
295
+
296
+ # Insurance Strategy
297
+ if profile.user_type.lower() == "professional":
298
+ plan.append(f"\n🛡️ **Insurance Protection**")
299
+ term_coverage = profile.monthly_income * 12 * 10
300
+ term_premium_estimate = term_coverage / 1000 # Rough estimate
301
+ plan.append(f"Term life insurance: ₹{term_coverage:,.0f}")
302
+ plan.append(f"Estimated premium: ₹{term_premium_estimate:,.0f}/month")
303
+ plan.append(f"Health insurance: ₹10L family floater recommended")
304
+
305
+ # Performance Analysis
306
+ plan.append(f"\n📈 **Current Performance Analysis**")
307
+ plan.append(f"Savings rate: {savings_rate:.1f}% {'✅ Excellent' if savings_rate > 30 else '⚠️ Needs improvement' if savings_rate > 20 else '🚨 Critical'}")
308
+ plan.append(f"Monthly surplus: ₹{savings:,.0f}")
309
+
310
+ if savings_rate < 20:
311
+ plan.append(f"💡 **Immediate Action**: Increase savings rate to 25% minimum")
312
+ plan.append(f"Target monthly savings: ₹{profile.monthly_income * 0.25:,.0f}")
313
+
314
+ return "\n".join(plan)
315
+
316
+ def build_enhanced_prompt(profile: UserProfile, summary: Dict, user_query: str) -> str:
317
+ """Build enhanced prompt for AI with comprehensive context"""
318
+
319
+ context = f"""
320
+ FINANCIAL PROFILE:
321
+ - User Type: {profile.user_type}
322
+ - Monthly Income: ₹{profile.monthly_income:,.0f}
323
+ - Risk Tolerance: {profile.risk_tolerance}
324
+ - Financial Goals: {profile.goals}
325
+ - Current Savings Rate: {summary['savings_rate_pct']:.1f}%
326
+ - Monthly Surplus: ₹{summary['net_savings']:,.0f}
327
+
328
+ EXPENSE ANALYSIS:
329
+ - Total Monthly Expenses: ₹{summary['expense_total']:,.0f}
330
+ - Top Spending Categories: {', '.join([f"{k}: ₹{v:,.0f}" for k, v in list(summary.get('top_expenses', {}).items())[:3]])}
331
+
332
+ USER QUERY: {user_query}
333
+
334
+ INSTRUCTIONS:
335
+ As FinanceAI, provide specific, actionable financial advice for Indian markets. Include:
336
+ 1. Exact amounts and calculations
337
+ 2. Specific investment products (fund names, tax sections)
338
+ 3. Expected returns and time horizons
339
+ 4. Implementation steps
340
+ 5. Risk considerations
341
+
342
+ Use current Indian financial regulations, tax laws (FY 2024-25), and market conditions.
343
+ Be conversational but professional. Include emojis for better readability.
344
+ """
345
+
346
+ return context
347
+
348
+ INTENT_PATTERNS = {
349
+ "savings": r"save|savings|emergency|fd|rd|goal|corpus",
350
+ "tax": r"tax|80c|deduction|income tax|regime|tds|refund|section",
351
+ "invest": r"invest|sip|mutual fund|stock|index|portfolio|asset|equity|debt",
352
+ "budget": r"budget|spend|expense|track|summary|report|category",
353
+ "insurance": r"insurance|term|health|life|cover|premium|policy",
354
+ "retirement": r"retirement|pension|retire|old age|corpus",
355
+ "loan": r"loan|emi|mortgage|credit|debt|interest rate"
356
+ }
357
+
358
+ def detect_intent(text: str) -> str:
359
+ t = text.lower()
360
+ for intent, pattern in INTENT_PATTERNS.items():
361
+ if re.search(pattern, t):
362
+ return intent
363
+ return "general"
364
+
365
+ # Modern Styling
366
+ st.markdown("""
367
+ <style>
368
+ .main-header {
369
+ text-align: center;
370
+ padding: 2rem 0;
371
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
372
+ -webkit-background-clip: text;
373
+ -webkit-text-fill-color: transparent;
374
+ font-size: 3.5rem;
375
+ font-weight: 800;
376
+ margin-bottom: 1rem;
377
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
378
+ }
379
+ .subtitle {
380
+ text-align: center;
381
+ color: #6b7280;
382
+ font-size: 1.3rem;
383
+ margin-bottom: 2rem;
384
+ font-weight: 500;
385
+ }
386
+ .ai-badge {
387
+ background: linear-gradient(45deg, #10b981, #3b82f6);
388
+ color: white;
389
+ padding: 0.5rem 1rem;
390
+ border-radius: 20px;
391
+ font-size: 0.9rem;
392
+ font-weight: 600;
393
+ display: inline-block;
394
+ margin: 0.5rem 0;
395
+ }
396
+ .financial-plan {
397
+ background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
398
+ border-left: 5px solid #0ea5e9;
399
+ padding: 1.5rem;
400
+ margin: 1rem 0;
401
+ border-radius: 10px;
402
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
403
+ }
404
+ .metric-card {
405
+ background: white;
406
+ border-radius: 12px;
407
+ padding: 1.5rem;
408
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
409
+ border: 1px solid #e2e8f0;
410
+ text-align: center;
411
+ }
412
+ .chat-container {
413
+ max-width: 900px;
414
+ margin: 0 auto;
415
+ padding: 0 1rem;
416
+ }
417
+ </style>
418
+ """, unsafe_allow_html=True)
419
+
420
+ # Header
421
+ st.markdown('<h1 class="main-header">🤖 FinanceAI</h1>', unsafe_allow_html=True)
422
+ st.markdown('<p class="subtitle">AI-Powered Financial Advisor with GPT Intelligence</p>', unsafe_allow_html=True)
423
+
424
+ # AI Status Badge
425
+ if OPENAI_AVAILABLE and os.environ.get("OPENAI_API_KEY"):
426
+ st.markdown('<div class="ai-badge">🚀 Powered by OpenAI GPT-4 • Maximum Accuracy</div>', unsafe_allow_html=True)
427
+ else:
428
+ st.markdown('<div class="ai-badge">⚡ Enhanced AI Fallback • Smart Responses</div>', unsafe_allow_html=True)
429
+
430
+ # Quick Setup
431
+ with st.expander("⚙️ Financial Profile Setup", expanded=True):
432
+ col1, col2, col3 = st.columns(3)
433
+ with col1:
434
+ monthly_income = st.number_input("💰 Monthly Income (₹)", min_value=0, value=50000, step=5000, help="Your total monthly earnings")
435
+ user_type = st.selectbox("👤 Profile Type", ["Professional", "Student"], index=0)
436
+ with col2:
437
+ risk = st.selectbox("📊 Risk Tolerance", ["Conservative", "Moderate", "Aggressive"], index=1, help="Your comfort level with investment risk")
438
+ uploaded = st.file_uploader("📄 Upload Transactions (CSV)", type=["csv"], help="Optional: Upload your expense data")
439
+ with col3:
440
+ provider_choice = st.selectbox("🤖 AI Engine", ["OpenAI GPT-4 (Recommended)", "Smart Fallback"], index=0)
441
+ goals = st.text_input("🎯 Financial Goals", value="Tax saving, wealth building, retirement planning", help="Your financial objectives")
442
+
443
+ # Create profile
444
+ profile = UserProfile(
445
+ name="User", user_type=user_type, age=28, country="India",
446
+ monthly_income=float(monthly_income), risk_tolerance=risk.lower(), goals=goals
447
+ )
448
+
449
+ # Initialize AI Providers
450
+ if not st.session_state.provider_inited:
451
+ openai_provider = OpenAIProvider()
452
+ hf_provider = HuggingFaceProvider()
453
+
454
+ if provider_choice.startswith("OpenAI") and openai_provider.available:
455
+ chosen_provider = openai_provider
456
+ else:
457
+ chosen_provider = hf_provider
458
+
459
+ st.session_state.provider = chosen_provider
460
+ st.session_state.provider_inited = True
461
+
462
+ provider = st.session_state.provider
463
+
464
+ # Load and analyze financial data
465
+ df = load_transactions(uploaded)
466
+ summary = budget_summary(df, monthly_income_hint=profile.monthly_income)
467
+
468
+ # Financial Overview
469
+ st.markdown("### 📊 Financial Dashboard")
470
+ col1, col2, col3, col4 = st.columns(4)
471
+
472
+ with col1:
473
+ st.metric("💰 Monthly Income", f"₹{summary['income_total']:,.0f}", help="Total monthly earnings")
474
+ with col2:
475
+ st.metric("💸 Expenses", f"₹{summary['expense_total']:,.0f}", help="Total monthly spending")
476
+ with col3:
477
+ st.metric("🎯 Net Savings", f"₹{summary['net_savings']:,.0f}", help="Monthly surplus amount")
478
+ with col4:
479
+ savings_color = "normal" if summary['savings_rate_pct'] > 20 else "inverse"
480
+ st.metric("📈 Savings Rate", f"{summary['savings_rate_pct']:.1f}%", help="Percentage of income saved")
481
+
482
+ st.divider()
483
+
484
+ # AI-Generated Financial Plan
485
+ ai_plan = generate_ai_financial_plan(profile, summary)
486
+ st.markdown("### 🎯 AI-Generated Financial Plan")
487
+ st.markdown(f'<div class="financial-plan">{ai_plan}</div>', unsafe_allow_html=True)
488
+
489
+ st.divider()
490
+
491
+ # Enhanced Chat Interface
492
+ st.markdown('<div class="chat-container">', unsafe_allow_html=True)
493
+ st.markdown("### 💬 Ask Your Financial Questions")
494
+
495
+ # Display chat history
496
+ for turn in st.session_state.chat_history:
497
+ avatar = "🤖" if turn["role"] == "assistant" else "👤"
498
+ with st.chat_message(turn["role"], avatar=avatar):
499
+ st.markdown(turn["content"])
500
+
501
+ # Chat input
502
+ user_msg = st.chat_input("💬 Ask anything about investments, taxes, savings, or financial planning...")
503
+
504
+ if user_msg:
505
+ # Add user message
506
+ st.session_state.chat_history.append({"role": "user", "content": user_msg})
507
+
508
+ # Detect intent and build enhanced prompt
509
+ intent = detect_intent(user_msg)
510
+ enhanced_prompt = build_enhanced_prompt(profile, summary, user_msg)
511
+
512
+ # Generate AI response
513
+ with st.chat_message("assistant", avatar="🤖"):
514
+ with st.spinner(f"🧠 {provider.name} is analyzing your query..."):
515
+ try:
516
+ ai_response = provider.generate(enhanced_prompt, max_tokens=1000)
517
+
518
+ # Enhance response with intent-specific formatting
519
+ if intent == "tax":
520
+ ai_response = f"📊 **Tax Optimization Advice**\n\n{ai_response}"
521
+ elif intent == "invest":
522
+ ai_response = f"🚀 **Investment Strategy**\n\n{ai_response}"
523
+ elif intent == "savings":
524
+ ai_response = f"💰 **Savings Plan**\n\n{ai_response}"
525
+ elif intent == "insurance":
526
+ ai_response = f"🛡️ **Insurance Strategy**\n\n{ai_response}"
527
+
528
+ except Exception as e:
529
+ ai_response = f"⚠️ **AI Service Temporarily Unavailable**\n\nI apologize for the inconvenience. Here's a quick response based on your query:\n\n"
530
+
531
+ # Fallback responses based on intent
532
+ if intent == "tax":
533
+ ai_response += "For tax optimization:\n• Invest ₹12,500/month in ELSS for Section 80C\n• Consider NPS for additional ₹50,000 deduction\n• Use tax-saving FDs for conservative investors"
534
+ elif intent == "invest":
535
+ ai_response += f"For investment strategy:\n• Monthly SIP: ₹{summary['net_savings']*.6:.0f} in equity funds\n• Emergency fund: ₹{summary['net_savings']*.3:.0f} in liquid funds\n• Debt allocation: ₹{summary['net_savings']*.1:.0f} in debt funds"
536
+ else:
537
+ ai_response += "Please check your internet connection and try again. For immediate help, consider:\n• Building 6-month emergency fund\n• Starting systematic investment plans\n• Optimizing tax-saving investments"
538
+
539
+ st.markdown(ai_response)
540
+
541
+ # Add AI response to history
542
+ st.session_state.chat_history.append({"role": "assistant", "content": ai_response})
543
+
544
+ st.markdown('</div>', unsafe_allow_html=True)
545
+
546
+ # Enhanced Footer
547
+ st.markdown("""
548
+ <div style="text-align: center; padding: 3rem 2rem; background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); border-radius: 15px; margin-top: 3rem; border: 1px solid #cbd5e1;">
549
+ <h3 style="color: #1e293b; margin-bottom: 1rem;">🤖 FinanceAI</h3>
550
+ <p style="color: #475569; font-size: 1.1rem; margin-bottom: 0.5rem;"><strong>AI-Powered Financial Intelligence</strong></p>
551
+ <p style="color: #64748b; font-size: 0.95rem;">Powered by advanced AI models • Personalized recommendations • Always verify with current regulations</p>
552
+ <div style="margin-top: 1rem; font-size: 0.85rem; color: #94a3b8;">
553
+ 🔒 Secure • 🎯 Accurate • 📊 Data-Driven • 🇮🇳 India-Focused
554
+ </div>
555
+ </div>
556
+ """, unsafe_allow_html=True)