Spaces:
Sleeping
Sleeping
| import os | |
| from openai import OpenAI | |
| API_KEY = os.getenv("OPENAI_API_KEY", "YOUR_OPENAI_API_KEY") | |
| client = OpenAI(api_key=API_KEY) | |
| def explain_savings_plan(payload: dict) -> str: | |
| """ | |
| Uses a small LLM model to turn the numeric savings plan into a | |
| short, plain-English explanation. | |
| Guardrails: | |
| - MUST NOT invent or change any numbers | |
| - Uses ONLY the fields in `payload` | |
| - Explanation only; it does not make credit decisions | |
| """ | |
| system_prompt = """ | |
| You are an AI coach explaining a down-payment savings plan for a first-time homebuyer. | |
| Rules: | |
| - Do NOT invent or change any numeric values. | |
| - Use ONLY the numbers provided in the JSON. | |
| - Be clear, friendly, and non-promotional. | |
| - Write 3–4 short sentences, no bullet points. | |
| Content to cover: | |
| 1) Start with the goal: buying a home at the given home_budget with the given down_payment_percent. | |
| 2) Explain how much they already have (current_savings) and how much more they need (remaining_need). | |
| 3) Explain the recommended_monthly_savings over timeline_years / timeline_months. | |
| 4) If savings_to_income_ratio is provided: | |
| - Briefly say whether this monthly amount is a light, moderate, or heavy lift | |
| (around 0.10 = light, 0.20 = moderate, 0.30+ = heavy), BUT use only that ratio, | |
| do not guess at after-tax income. | |
| 5) Encourage them to adjust the timeline or budget sliders if the amount feels too high. | |
| """.strip() | |
| user_content = f"Here is the JSON for this user's plan: {payload}" | |
| try: | |
| completion = client.chat.completions.create( | |
| model="gpt-4.1-mini", | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": user_content}, | |
| ], | |
| max_tokens=230, | |
| temperature=0.35, | |
| ) | |
| explanation = completion.choices[0].message.content.strip() | |
| return explanation | |
| except Exception: | |
| # Safe fallback if the LLM call fails | |
| hb = payload.get("home_budget") | |
| dp_pct = payload.get("down_payment_percent") | |
| dp_amt = payload.get("down_payment_amount") | |
| rem = payload.get("remaining_need") | |
| m = payload.get("timeline_months") | |
| rec = payload.get("recommended_monthly_savings") | |
| return ( | |
| "We calculated your plan using your home budget, down-payment percentage, " | |
| f"and current savings. For example, to buy a home around ${hb:,} with a " | |
| f"{dp_pct}% down payment (about ${dp_amt:,}), you still need roughly " | |
| f"${rem:,}. Spreading that over about {m} months leads to a recommended " | |
| f"savings of about ${rec:,} per month, including closing cost and interest assumptions." | |
| ) | |