Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,180 +1,120 @@
|
|
| 1 |
-
import
|
| 2 |
-
import json
|
| 3 |
-
import random
|
| 4 |
-
import datetime
|
| 5 |
-
from flask import Flask, request, jsonify
|
| 6 |
from transformers import pipeline
|
| 7 |
-
|
| 8 |
|
| 9 |
app = Flask(__name__)
|
| 10 |
|
| 11 |
-
#
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
)
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
# 🧠 Memory System (temp memory)
|
| 22 |
-
# ------------------------------
|
| 23 |
-
MEMORY_FILE = "chat_memory.json"
|
| 24 |
-
MEMORY_DURATION_DAYS = 15
|
| 25 |
-
|
| 26 |
-
def load_memory():
|
| 27 |
-
if os.path.exists(MEMORY_FILE):
|
| 28 |
-
with open(MEMORY_FILE, "r") as f:
|
| 29 |
return json.load(f)
|
| 30 |
return {}
|
| 31 |
|
| 32 |
-
def
|
| 33 |
-
with open(
|
| 34 |
-
json.dump(
|
| 35 |
-
|
| 36 |
-
def clear_old_memory(memory):
|
| 37 |
-
now = datetime.datetime.now()
|
| 38 |
-
updated = {}
|
| 39 |
-
for user, data in memory.items():
|
| 40 |
-
chat_time = datetime.datetime.fromisoformat(data["last_chat"])
|
| 41 |
-
if (now - chat_time).days < MEMORY_DURATION_DAYS:
|
| 42 |
-
updated[user] = data
|
| 43 |
-
return updated
|
| 44 |
-
|
| 45 |
-
memory = load_memory()
|
| 46 |
-
memory = clear_old_memory(memory)
|
| 47 |
-
save_memory(memory)
|
| 48 |
-
|
| 49 |
-
# ------------------------------
|
| 50 |
-
# 🆘 Crisis Detection
|
| 51 |
-
# ------------------------------
|
| 52 |
-
def detect_crisis(text):
|
| 53 |
-
crisis_signals = [
|
| 54 |
-
"end my life", "kill myself", "hurt myself", "suicide",
|
| 55 |
-
"i don't want to live", "i want to die", "can't go on"
|
| 56 |
-
]
|
| 57 |
-
return any(signal in text.lower() for signal in crisis_signals)
|
| 58 |
-
|
| 59 |
-
# Geo-based crisis helpline lookup
|
| 60 |
-
def get_geo_helpline(location_query="world"):
|
| 61 |
-
helplines = {
|
| 62 |
-
"india": "AASRA Helpline: 91-9820466726 or 91-22-27546669",
|
| 63 |
-
"usa": "988 Suicide and Crisis Lifeline: Call or text 988",
|
| 64 |
-
"uk": "Samaritans Helpline: 116 123",
|
| 65 |
-
"canada": "Talk Suicide Canada: 1-833-456-4566",
|
| 66 |
-
"australia": "Lifeline Australia: 13 11 14",
|
| 67 |
-
"world": "Find help near you: https://findahelpline.com, available worldwide 🌍"
|
| 68 |
-
}
|
| 69 |
-
for key, number in helplines.items():
|
| 70 |
-
if key in location_query.lower():
|
| 71 |
-
return number
|
| 72 |
-
return helplines["world"]
|
| 73 |
-
|
| 74 |
-
# ------------------------------
|
| 75 |
-
# 💛 Empathetic Response Enrichment
|
| 76 |
-
# ------------------------------
|
| 77 |
-
empathetic_openings = [
|
| 78 |
-
"That sounds really tough, and I appreciate you sharing it with me.",
|
| 79 |
-
"It must be hard to go through that — I’m here to listen.",
|
| 80 |
-
"I can sense that this means a lot to you.",
|
| 81 |
-
"You’re opening up about something important — thank you for trusting me.",
|
| 82 |
-
"It’s okay to feel this way; you’re not alone.",
|
| 83 |
-
"That must have been difficult, but I’m proud that you’re expressing it.",
|
| 84 |
-
]
|
| 85 |
-
|
| 86 |
-
follow_up_questions = [
|
| 87 |
-
"Would you like to talk more about what’s been making you feel that way?",
|
| 88 |
-
"How have things been since then?",
|
| 89 |
-
"What’s been on your mind lately?",
|
| 90 |
-
"Has something specific been triggering those feelings?",
|
| 91 |
-
"What helps you feel a bit better when things get heavy?",
|
| 92 |
-
]
|
| 93 |
-
|
| 94 |
-
def enrich_response(reply_text):
|
| 95 |
-
if reply_text.strip().lower() in ["i understand", "i see", "okay", "hmm"]:
|
| 96 |
-
return random.choice(empathetic_openings)
|
| 97 |
-
|
| 98 |
-
if any(word in reply_text.lower() for word in ["understand", "sorry", "feel", "hard", "sad"]):
|
| 99 |
-
addition = random.choice(follow_up_questions)
|
| 100 |
-
reply_text = random.choice(empathetic_openings) + " " + reply_text + " " + addition
|
| 101 |
-
|
| 102 |
-
return reply_text
|
| 103 |
-
|
| 104 |
-
# ------------------------------
|
| 105 |
-
# 🧠 Generate AI Response (Simulated)
|
| 106 |
-
# ------------------------------
|
| 107 |
-
def generate_supportive_reply(user_input, user_name, user_age):
|
| 108 |
-
emotions = emotion_analyzer(user_input)[0]
|
| 109 |
-
dominant_emotion = max(emotions, key=lambda x: x["score"])["label"].lower()
|
| 110 |
-
|
| 111 |
-
# Crisis response
|
| 112 |
-
if detect_crisis(user_input):
|
| 113 |
-
geo = Nominatim(user_agent="support_bot").geocode("your location") or None
|
| 114 |
-
location = geo.address if geo else "world"
|
| 115 |
-
helpline = get_geo_helpline(location)
|
| 116 |
-
return (
|
| 117 |
-
f"{user_name}, I’m really sorry that you’re feeling this way. "
|
| 118 |
-
f"You are not alone, and help is available. 💛\n\n"
|
| 119 |
-
f"If you are in immediate danger, please reach out to your local emergency number.\n"
|
| 120 |
-
f"{helpline}"
|
| 121 |
-
)
|
| 122 |
-
|
| 123 |
-
# Emotion-based support
|
| 124 |
-
emotion_responses = {
|
| 125 |
-
"joy": f"That’s lovely to hear, {user_name}! 😊 It’s great to see things that make you happy.",
|
| 126 |
-
"sadness": f"I can sense you’re going through something difficult, {user_name}. You don’t have to face it alone.",
|
| 127 |
-
"anger": f"I hear the frustration in your words, {user_name}. It’s okay to feel angry — what’s been causing it?",
|
| 128 |
-
"fear": f"That sounds scary, {user_name}. You’re safe here — do you want to tell me more about what’s worrying you?",
|
| 129 |
-
"love": f"That’s beautiful, {user_name}. Love can be healing and powerful — how does it make you feel lately?",
|
| 130 |
-
"surprise": f"Wow, that sounds unexpected! How are you feeling about it, {user_name}?"
|
| 131 |
-
}
|
| 132 |
-
|
| 133 |
-
base_reply = emotion_responses.get(dominant_emotion, f"I’m here for you, {user_name}. Tell me more about what’s on your mind.")
|
| 134 |
-
return enrich_response(base_reply)
|
| 135 |
-
|
| 136 |
-
# ------------------------------
|
| 137 |
-
# 🌐 Flask Routes
|
| 138 |
-
# ------------------------------
|
| 139 |
-
@app.route('/')
|
| 140 |
-
def home():
|
| 141 |
-
return jsonify({"message": "💛 Emotional Support Chatbot API is running!"})
|
| 142 |
-
|
| 143 |
-
@app.route('/chat', methods=['POST'])
|
| 144 |
-
def chat():
|
| 145 |
-
global memory
|
| 146 |
-
data = request.get_json()
|
| 147 |
-
user_input = data.get('message', '').strip()
|
| 148 |
-
user_name = data.get('name', 'Friend')
|
| 149 |
-
user_age = data.get('age', '20')
|
| 150 |
|
| 151 |
-
|
| 152 |
-
|
|
|
|
|
|
|
| 153 |
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
|
|
|
|
|
|
| 171 |
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
|
|
|
|
|
|
|
|
|
| 176 |
|
| 177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
|
| 179 |
if __name__ == "__main__":
|
| 180 |
app.run(host="0.0.0.0", port=7860)
|
|
|
|
| 1 |
+
from flask import Flask, request, jsonify, send_from_directory
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from transformers import pipeline
|
| 3 |
+
import json, os, datetime
|
| 4 |
|
| 5 |
app = Flask(__name__)
|
| 6 |
|
| 7 |
+
# load emotion model
|
| 8 |
+
emotion_analyzer = pipeline("text-classification",
|
| 9 |
+
model="j-hartmann/emotion-english-distilroberta-base",
|
| 10 |
+
top_k=None)
|
| 11 |
+
|
| 12 |
+
DATA_FILE = "user_data.json"
|
| 13 |
+
|
| 14 |
+
def load_user_data():
|
| 15 |
+
if os.path.exists(DATA_FILE):
|
| 16 |
+
with open(DATA_FILE, "r") as f:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
return json.load(f)
|
| 18 |
return {}
|
| 19 |
|
| 20 |
+
def save_user_data(data):
|
| 21 |
+
with open(DATA_FILE, "w") as f:
|
| 22 |
+
json.dump(data, f, indent=2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
+
def detect_emotion(text):
|
| 25 |
+
result = emotion_analyzer(text)[0]
|
| 26 |
+
scores = {r["label"]: r["score"] for r in result}
|
| 27 |
+
return max(scores, key=scores.get)
|
| 28 |
|
| 29 |
+
def crisis_check(text):
|
| 30 |
+
crisis_keywords = ["end my life", "kill myself", "suicide", "hurt myself"]
|
| 31 |
+
for word in crisis_keywords:
|
| 32 |
+
if word in text.lower():
|
| 33 |
+
return True
|
| 34 |
+
return False
|
| 35 |
|
| 36 |
+
@app.route("/chat", methods=["POST"])
|
| 37 |
+
def chat():
|
| 38 |
+
data = request.get_json()
|
| 39 |
+
user_message = data.get("message", "")
|
| 40 |
+
user_info = load_user_data()
|
| 41 |
+
user_name = user_info.get("name", "friend")
|
| 42 |
+
user_age = user_info.get("age", None)
|
| 43 |
+
emotion = detect_emotion(user_message)
|
| 44 |
+
|
| 45 |
+
# save mood history
|
| 46 |
+
now = datetime.datetime.now().strftime("%Y-%m-%d")
|
| 47 |
+
user_info["last_mood"] = emotion
|
| 48 |
+
user_info["last_seen"] = now
|
| 49 |
+
save_user_data(user_info)
|
| 50 |
+
|
| 51 |
+
# crisis check
|
| 52 |
+
if crisis_check(user_message):
|
| 53 |
+
return jsonify({
|
| 54 |
+
"reply": f"{user_name}, you matter. You're not alone. If you’re in danger, please reach out to your local emergency helpline or someone you trust immediately ❤️",
|
| 55 |
+
"emotion": "crisis"
|
| 56 |
+
})
|
| 57 |
+
|
| 58 |
+
empathy_responses = [
|
| 59 |
+
"That sounds tough, but I’m here for you.",
|
| 60 |
+
"I can sense how that feels. Tell me more, if you want.",
|
| 61 |
+
"That must be hard, but you’re doing better than you think.",
|
| 62 |
+
"I appreciate you sharing this with me.",
|
| 63 |
+
"Sometimes words aren’t enough, but I’m listening fully.",
|
| 64 |
+
"You’ve been strong for so long — it’s okay to let go here.",
|
| 65 |
+
"I hear you, truly. You’re safe here."
|
| 66 |
+
]
|
| 67 |
|
| 68 |
+
supportive_followups = [
|
| 69 |
+
"Would you like to talk more about what’s been on your mind?",
|
| 70 |
+
"Sometimes sharing even small details helps a little. Want to try?",
|
| 71 |
+
"Would you like something calming, or maybe a bit of motivation?"
|
| 72 |
+
]
|
| 73 |
|
| 74 |
+
motivational_quotes = [
|
| 75 |
+
"Every sunrise brings a new chance to begin again 🌅",
|
| 76 |
+
"Even the darkest nights end with the light of dawn.",
|
| 77 |
+
"You’ve made it through 100% of your hardest days so far 💪",
|
| 78 |
+
"Storms make trees take deeper roots.",
|
| 79 |
+
"You are allowed to rest, not to quit."
|
| 80 |
+
]
|
| 81 |
|
| 82 |
+
import random
|
| 83 |
+
reply = ""
|
| 84 |
+
|
| 85 |
+
if "name" not in user_info or "age" not in user_info:
|
| 86 |
+
if "name" not in user_info:
|
| 87 |
+
reply = "Hey there! What’s your name?"
|
| 88 |
+
user_info["awaiting"] = "name"
|
| 89 |
+
elif "age" not in user_info:
|
| 90 |
+
reply = f"Nice to meet you, {user_name}! How old are you?"
|
| 91 |
+
user_info["awaiting"] = "age"
|
| 92 |
+
save_user_data(user_info)
|
| 93 |
+
elif user_info.get("awaiting") == "name":
|
| 94 |
+
user_info["name"] = user_message.strip().split()[0]
|
| 95 |
+
reply = f"Lovely to meet you, {user_info['name']}! How old are you?"
|
| 96 |
+
user_info["awaiting"] = "age"
|
| 97 |
+
save_user_data(user_info)
|
| 98 |
+
elif user_info.get("awaiting") == "age":
|
| 99 |
+
user_info["age"] = user_message.strip().split()[0]
|
| 100 |
+
reply = f"Got it! So {user_info['age']} it is. How are you feeling today?"
|
| 101 |
+
user_info.pop("awaiting", None)
|
| 102 |
+
save_user_data(user_info)
|
| 103 |
+
elif "guidance" in user_message.lower() or "motivation" in user_message.lower():
|
| 104 |
+
reply = random.choice(motivational_quotes)
|
| 105 |
+
else:
|
| 106 |
+
if emotion in ["sadness", "fear", "anger"]:
|
| 107 |
+
reply = random.choice(empathy_responses) + " " + random.choice(supportive_followups)
|
| 108 |
+
elif emotion in ["joy", "love"]:
|
| 109 |
+
reply = f"That’s wonderful, {user_name}! I’m so glad to hear it 🌟"
|
| 110 |
+
else:
|
| 111 |
+
reply = random.choice(motivational_quotes)
|
| 112 |
+
|
| 113 |
+
return jsonify({"reply": reply, "emotion": emotion})
|
| 114 |
+
|
| 115 |
+
@app.route("/")
|
| 116 |
+
def index():
|
| 117 |
+
return send_from_directory(".", "index.html")
|
| 118 |
|
| 119 |
if __name__ == "__main__":
|
| 120 |
app.run(host="0.0.0.0", port=7860)
|