Spaces:
Sleeping
Sleeping
| import os | |
| from dotenv import load_dotenv | |
| from openai import OpenAI | |
| from backend import expense_manager | |
| load_dotenv() | |
| client = OpenAI( | |
| api_key=os.environ.get("GROQ_API_KEY"), | |
| base_url="https://api.groq.com/openai/v1", | |
| ) | |
| def suggest_budget(user_id: str, expenses=None): | |
| """ | |
| Analyze user expenses and return a budget suggestion using Groq AI. | |
| Input: user_id and optional expense list | |
| Output: dictionary with numeric split + AI explanation | |
| Example: | |
| { | |
| "Spending": 0.6, | |
| "Savings": 0.3, | |
| "Investments": 0.1, | |
| "message": "You spend most on rent, consider lowering entertainment." | |
| } | |
| """ | |
| if expenses is None: | |
| expenses = expense_manager.list_expenses(user_id) | |
| if not expenses: | |
| return { | |
| "Spending": 0.6, | |
| "Savings": 0.3, | |
| "Investments": 0.1, | |
| "message": "No expense data found — using default 60/30/10 split." | |
| } | |
| summary_lines = [] | |
| for e in expenses: | |
| summary_lines.append(f"{e['name']}: {e['amount']} ({e['category']}) on {e['date']}") | |
| summary_text = "\n".join(summary_lines) | |
| prompt = f""" | |
| You are FinSync AI, a financial budgeting assistant. | |
| User's Expense Summary: | |
| {summary_text} | |
| Task: | |
| 1. Analyze how the user spends money. | |
| 2. Suggest an ideal percentage allocation among: | |
| - Spending (daily essentials, bills, rent) | |
| - Savings (emergency fund) | |
| - Investments (future growth) | |
| 3. Return result in strict JSON format like this: | |
| {{ | |
| "Spending": 0.55, | |
| "Savings": 0.30, | |
| "Investments": 0.15, | |
| "message": "Short reasoning or advice" | |
| }} | |
| """ | |
| try: | |
| response = client.responses.create( | |
| model=GROQ_MODEL, | |
| input=prompt, | |
| temperature=0.3 | |
| ) | |
| ai_text = response.output_text.strip() | |
| import json, re | |
| json_match = re.search(r"\{[\s\S]*\}", ai_text) | |
| if json_match: | |
| parsed = json.loads(json_match.group(0)) | |
| for k in ["Spending", "Savings", "Investments"]: | |
| if k not in parsed: | |
| parsed[k] = 0.0 | |
| return parsed | |
| else: | |
| return { | |
| "Spending": 0.6, | |
| "Savings": 0.3, | |
| "Investments": 0.1, | |
| "message": ai_text or "AI could not parse response properly." | |
| } | |
| except Exception as e: | |
| return { | |
| "Spending": 0.6, | |
| "Savings": 0.3, | |
| "Investments": 0.1, | |
| "message": f"Groq API error: {e}" | |
| } |