Spaces:
Runtime error
Runtime error
| import os | |
| import json | |
| import random | |
| import requests | |
| from datetime import datetime, timedelta | |
| from flask import Flask, request, jsonify | |
| from transformers import AutoTokenizer, AutoModelForSequenceClassification | |
| import torch | |
| from openai import OpenAI | |
| app = Flask(__name__) | |
| # Initialize OpenAI client | |
| client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
| # Load emotion model | |
| tokenizer = AutoTokenizer.from_pretrained("j-hartmann/emotion-english-distilroberta-base") | |
| model = AutoModelForSequenceClassification.from_pretrained("j-hartmann/emotion-english-distilroberta-base") | |
| emotion_labels = [ | |
| "anger", | |
| "disgust", | |
| "fear", | |
| "joy", | |
| "neutral", | |
| "sadness", | |
| "surprise" | |
| ] | |
| # Motivational / spiritual quotes (non-religious and respectful) | |
| motivational_quotes = [ | |
| "Believe you can and you’re halfway there.", | |
| "Every day is a new beginning; take a deep breath and start again.", | |
| "The only way out is through. You’ve got this.", | |
| "Storms don’t last forever — keep moving forward.", | |
| "Even the smallest step in the right direction is progress.", | |
| "You are stronger than you think and more capable than you realize.", | |
| "Let your hope, not your hurt, shape your future.", | |
| "Peace begins the moment you choose to stop fighting yourself.", | |
| "Light will always find its way through the cracks.", | |
| "Take things one heartbeat at a time — you are doing enough." | |
| ] | |
| # Path for storing user data | |
| USER_DATA_FILE = "user_data.json" | |
| 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": "", "age": "", "last_mood": "", "last_interaction": str(datetime.utcnow()), "missed_days": 0} | |
| def save_user_data(data): | |
| with open(USER_DATA_FILE, "w") as f: | |
| json.dump(data, f) | |
| def chat(): | |
| user_input = request.json.get("message", "") | |
| bot_text, emotion = generate_response(user_input) | |
| # ✅ Make sure to return both fields exactly like this: | |
| return jsonify({ | |
| "text": bot_text, | |
| "emotion": emotion | |
| }) | |
| # Emotion detection | |
| inputs = tokenizer(message, return_tensors="pt") | |
| with torch.no_grad(): | |
| outputs = model(**inputs) | |
| emotion_label = emotion_labels[int(torch.argmax(outputs.logits))] | |
| # Motivational or guidance request | |
| motivational_keywords = ["give me guidance", "i need motivation", "motivate me", "inspire me"] | |
| if any(kw in message.lower() for kw in motivational_keywords): | |
| quote = random.choice(motivational_quotes) | |
| ai_reply = f"Here’s something to lift your spirit, {user_name}: {quote}" | |
| else: | |
| # Empathetic chat completion | |
| system_prompt = f"You are a warm, kind, and empathetic emotional support assistant for {user_name}, age {user_age}. Be comforting and understanding, but not a therapist." | |
| response = client.chat.completions.create( | |
| model="gpt-4o-mini", | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": message}, | |
| ], | |
| ) | |
| ai_reply = response.choices[0].message.content.strip() | |
| # Daily check-in system | |
| last_time = datetime.fromisoformat(user_data.get("last_interaction", str(datetime.utcnow()))) | |
| now = datetime.utcnow() | |
| days_diff = (now - last_time).days | |
| if days_diff >= 1: | |
| user_data["missed_days"] += days_diff | |
| else: | |
| user_data["missed_days"] = 0 | |
| user_data.update({ | |
| "name": user_name, | |
| "age": user_age, | |
| "last_mood": emotion_label, | |
| "last_interaction": str(now) | |
| }) | |
| save_user_data(user_data) | |
| if user_data["missed_days"] >= 3: | |
| ai_reply = f"We missed you, {user_name}! Hope you’re okay. Remember, I’m always here to listen 💛" | |
| # Optional text-to-speech (non-blocking) | |
| try: | |
| speech_url = "https://api.openai.com/v1/audio/speech" | |
| headers = {"Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}"} | |
| payload = {"model": "gpt-4o-mini-tts", "voice": "alloy", "input": ai_reply} | |
| speech = requests.post(speech_url, headers=headers, json=payload) | |
| if speech.status_code == 200: | |
| with open("speech.mp3", "wb") as f: | |
| f.write(speech.content) | |
| else: | |
| print("Speech generation failed:", speech.text) | |
| except Exception as e: | |
| print("Speech block error:", e) | |
| return jsonify({"response": ai_reply, "emotion": emotion_label}) | |
| from flask import send_from_directory | |
| from flask import send_from_directory | |
| def index(): | |
| # Serve index.html from the same directory as app.py | |
| return send_from_directory(".", "index.html") | |
| # ✅ Ensure Flask knows what to serve | |
| if __name__ == "__main__": | |
| app.run(host="0.0.0.0", port=7860) | |
| # Required for Hugging Face Spaces / OneCompiler | |
| application = app | |
| # Hugging Face Spaces expects an app variable called "app" | |
| application = app |