Spaces:
Sleeping
Sleeping
| import os | |
| import json | |
| from datetime import datetime, timedelta | |
| from flask import Flask, request, jsonify, send_from_directory | |
| from transformers import pipeline | |
| from openai import OpenAI | |
| app = Flask(__name__) | |
| client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
| # Load Hugging Face emotion model | |
| emotion_analyzer = pipeline("text-classification", model="j-hartmann/emotion-english-distilroberta-base", top_k=None) | |
| USER_DATA_FILE = "user_data.json" | |
| # ---------------------- UTILITIES ------------------------- | |
| def load_user_data(): | |
| if os.path.exists(USER_DATA_FILE): | |
| with open(USER_DATA_FILE, "r") as f: | |
| return json.load(f) | |
| return {"name": None, "age": None, "mood": None, "last_interaction": None, "missed_days": 0} | |
| def save_user_data(data): | |
| with open(USER_DATA_FILE, "w") as f: | |
| json.dump(data, f, indent=4) | |
| def detect_emotion(text): | |
| result = emotion_analyzer(text) | |
| top_emotion = sorted(result[0], key=lambda x: x["score"], reverse=True)[0]["label"] | |
| return top_emotion.lower() | |
| def crisis_check(user_input, location="global"): | |
| crisis_keywords = ["kill myself", "end my life", "suicide", "die", "worthless"] | |
| if any(kw in user_input.lower() for kw in crisis_keywords): | |
| if location == "india": | |
| return ("I'm really sorry you’re feeling like this. You are not alone. " | |
| "You can reach out to AASRA Helpline at 91-9820466726 or Snehi at 91-9582208181.") | |
| elif location == "us": | |
| return ("It sounds like you’re going through a really difficult time. " | |
| "If you are in the U.S., please call or text 988 to connect with the Suicide and Crisis Lifeline.") | |
| else: | |
| return ("I’m so sorry you’re in pain right now. You are not alone. " | |
| "Please reach out to a local suicide helpline or emergency number right away.") | |
| return None | |
| def days_since_last_interaction(user_data): | |
| if not user_data.get("last_interaction"): | |
| return None | |
| last = datetime.fromisoformat(user_data["last_interaction"]) | |
| return (datetime.now() - last).days | |
| # ---------------------- PERSONALITY SYSTEM ------------------------- | |
| PERSONALITIES = { | |
| "calm": { | |
| "tone": "gentle, understanding, patient", | |
| "style": "Uses short, soft phrases and empathy-driven responses." | |
| }, | |
| "friendly": { | |
| "tone": "warm, chatty, and supportive", | |
| "style": "Uses casual language and light humor to uplift users." | |
| }, | |
| "deep": { | |
| "tone": "reflective, philosophical, soulful", | |
| "style": "Encourages self-reflection and growth." | |
| }, | |
| "spiritual": { | |
| "tone": "peaceful, grounding, and nurturing", | |
| "style": "Focuses on mindfulness, acceptance, and compassion." | |
| } | |
| } | |
| def generate_personality_prompt(personality): | |
| p = PERSONALITIES.get(personality, PERSONALITIES["calm"]) | |
| return f"You are an emotional support AI with a {p['tone']} tone. {p['style']} Respond to users with empathy and variation." | |
| # ---------------------- RESPONSE LOGIC ------------------------- | |
| def chat(): | |
| user_input = request.json.get("message", "") | |
| personality = request.json.get("personality", "calm") | |
| location = request.json.get("location", "global") | |
| user_data = load_user_data() | |
| # Crisis detection | |
| crisis_response = crisis_check(user_input, location) | |
| if crisis_response: | |
| return jsonify({"response": crisis_response, "emotion": "worried"}) | |
| # Daily check-in system | |
| days_passed = days_since_last_interaction(user_data) | |
| if days_passed is not None: | |
| if days_passed >= 3: | |
| reminder = "We missed you these past few days. How have you been feeling lately?" | |
| elif days_passed == 1 and user_data.get("mood") in ["sad", "angry", "worried"]: | |
| reminder = f"Hey {user_data.get('name','friend')}, you seemed a bit down yesterday. How are you feeling today?" | |
| else: | |
| reminder = None | |
| else: | |
| reminder = None | |
| # Emotion detection | |
| emotion = detect_emotion(user_input) | |
| user_data["mood"] = emotion | |
| user_data["last_interaction"] = datetime.now().isoformat() | |
| save_user_data(user_data) | |
| # OpenAI response generation | |
| system_prompt = generate_personality_prompt(personality) | |
| prompt = f""" | |
| The user said: "{user_input}" | |
| Their name: {user_data.get('name')} | |
| Their age: {user_data.get('age')} | |
| Their recent mood: {user_data.get('mood')} | |
| Your goal: offer empathetic emotional support, avoid repetition, vary expressions naturally. | |
| """ | |
| openai_reply = None | |
| try: | |
| response = client.chat.completions.create( | |
| model="gpt-4o-mini", | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| temperature=0.9 | |
| ) | |
| openai_reply = response.choices[0].message.content.strip() | |
| except Exception as e: | |
| print("Error with OpenAI API:", e) | |
| openai_reply = "I'm here for you, even though I’m having a bit of trouble expressing myself right now." | |
| # Combine reminder if needed | |
| if reminder: | |
| final_reply = f"{reminder} {openai_reply}" | |
| else: | |
| final_reply = openai_reply | |
| return jsonify({"response": final_reply, "emotion": emotion}) | |
| # ---------------------- FRONTEND ------------------------- | |
| def index(): | |
| return send_from_directory(".", "index.html") | |
| def static_files(path): | |
| return send_from_directory(".", path) | |
| # ---------------------- RUN ------------------------- | |
| if __name__ == "__main__": | |
| app.run(host="0.0.0.0", port=7860) |