File size: 5,010 Bytes
aa1953b
1bc072e
 
 
bee1bed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1bc072e
bee1bed
 
 
 
 
 
 
 
 
 
 
 
 
1bc072e
bee1bed
 
1bc072e
 
 
bee1bed
 
1bc072e
bee1bed
1bc072e
 
bee1bed
 
 
 
f933f3a
 
 
bee1bed
f933f3a
 
 
 
 
bee1bed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1bc072e
bee1bed
 
 
 
1bc072e
bee1bed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1bc072e
bee1bed
 
 
 
 
 
 
d879496
25109fa
 
 
 
 
 
 
 
 
 
 
 
a9e7acd
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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)
@app.route("/chat", methods=["POST"])
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
@app.route("/")
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