STRONGmind / app.py
iamstrong's picture
Upload 3 files
7c669fc verified
from gtts import gTTS
import tempfile
import json
import datetime
import gradio as gr
import re
import os
from openai import OpenAI
# OpenAI Configuration
# API key is loaded from environment variable OPENAI_API_KEY
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
raise ValueError("OPENAI_API_KEY environment variable is required")
client = OpenAI(api_key=OPENAI_API_KEY)
# System prompt for ChatGPT to act as a compassionate therapist
SYSTEM_PROMPT = """You are StrongMind Therapist - a compassionate, empathetic AI therapist designed to provide emotional support and mental health guidance.
Your role is to:
- Listen actively and validate the person's feelings
- Provide thoughtful, compassionate responses
- Offer practical coping strategies and mental health tips when appropriate
- Be supportive and non-judgmental
- Encourage them to seek professional help if needed
- Keep responses conversational and natural, like talking to a caring human counselor
- Be brief but warm (2-3 sentences typically, unless they ask for more detail)"""
# User data
user_info = {"name": "", "age": "", "gender": "", "language": "english" , "Guardian_info": ""}
chat_history = []
journal_entries = []
calm_tips = [
"Take 3 deep breaths.", "Listen to nature.", "Stretch your body.",
"Drink water.", "Think of one good thing today.", "Close your eyes for 1 minute.",
"Write your feelings.", "Smile at yourself.", "Imagine a peaceful place.",
"Say a positive affirmation."
]
study_tips = [
"Use Pomodoro: 25min study, 5min break", "Make a daily to-do list",
"Avoid multitasking", "Use color-coded notes", "Take 10-min exercise breaks",
"Sleep 7–9 hrs daily", "Drink water during study", "Use active recall",
"Study hardest topics first", "Test yourself often"
]
tip_index = {"calm": 0, "study": 0}
lang_codes = {
"english": "en", "hindi": "hi", "marathi": "mr", "bengali": "bn",
"tamil": "ta", "telugu": "te", "malayalam": "ml", "spanish": "es",
"french": "fr", "german": "de"
}
# List of harmful or dangerous keywords
harmful_keywords = [
"abomination", "annihilate", "arson", "ass", "assault", "atrocity",
"backstab", "barbaric", "barbarian", "beast", "belittle", "berserk",
"betray", "betrayal", "bigot", "blacklist", "blood", "bloodbath",
"bloody", "bomb", "bonehead", "brainless", "brutal", "brute", "burn",
"butcher", "cage", "callous", "cancer", "chaos", "cheater", "cold-blooded",
"conman", "corrupt", "cowardly", "crash", "crime", "criminality", "crook",
"cruel", "cruelty", "curseword", "damage", "danger", "dangerous", "deadly",
"deceive", "defame", "defeat", "degenerate", "demon", "despise", "destroy",
"destruction", "destructive", "devastate", "devil", "diabolical", "dictator",
"dirty", "disaster", "dishonor", "disrespect", "disturb", "divisive", "drunk",
"dumbass", "dungeon", "enemies", "enemy", "enrage", "evilness", "exile",
"exploit", "exterminate", "fake", "fanatic", "fascist", "fatal", "fire",
"forgery", "fraud", "fraudster", "freakish", "gang", "gangster", "ghastly",
"ghoul", "gory", "grotesque", "gruesome", "hag", "halfwit", "hardhearted",
"harm", "hateable", "hateful", "havoc", "hell", "hellish", "heretic",
"hideous", "horrid", "horrific", "hostility", "howl", "hypocrite", "illegal",
"illicit", "immoral", "imposter", "injure", "insensitive", "insidious",
"intolerant", "irate", "jerky", "joke", "joker", "kidnap", "killjoy", "liar",
"loath", "loathsome", "lowlife", "madness", "malicious", "malign",
"manipulate", "menace", "monster", "monstrous", "mug", "murderous",
"mutant", "mutiny", "nasty", "nefarious", "neglect", "negative", "offend",
"offender", "ominous", "oppress", "outrage", "outrageous", "parasite",
"penalty", "perish", "pest", "plague", "poison", "poisonous", "pollute",
"psychopath", "punch", "punish", "punishment", "quarrel", "rage", "rat",
"rebellion", "reckless", "repel", "repulsive", "revolt", "revolting",
"rioter", "rob", "robber", "rotten", "ruin", "savage", "scare", "scary",
"schemer", "scold", "scorn", "scoundrel", "scream", "screwed", "serpent",
"shady", "sham", "shameful", "shatter", "shocking", "sin", "sinister",
"slavey", "slimy", "smash", "smite", "snob", "spite", "spiteful", "stab",
"stench", "stink", "strike", "subvert", "suspicious", "target", "tease",
"terrible", "terrify", "thief", "threat", "threaten", "thug", "torment",
"torture", "trap", "trick", "trigger", "trouble", "uncivilized", "undermine",
"unfair", "unjust", "unkind", "usurper", "vandal", "vandalize", "venom",
"venomous", "villain", "villainous", "vindictive", "violent", "viper",
"vulgarity", "war", "warmonger", "waste", "wickedness", "wild", "wound",
"wrath", "wreck", "wrong", "yell", "zombie","suicide", "kill myself", "end my life", "harm myself", "cut myself",
"want to die", "die", "jump off", "self-harm",
"suicide", "kill myself", "end my life", "harm myself", "cut myself",
"want to die", "die", "jump off", "self-harm", "give up", "not worth it",
"ending it all", "self-hate", "suicidal", "tragic", "trauma", "pain",
"painful", "sorrow",
"unworthy", "hurt", "grief", "agony", "doom", "doomed"
]
# Harmful word detection response
harmful_response = (
"⚠️ It sounds like you're going through a really tough time.\n\n"
"Please reach out to a professional:\n\n"
"🇮🇳 **India Helplines**\n"
"🧠 *Dr. Rachna Khanna Singh* – +91 99103 90559\n"
"📞 *iCall Helpline* – +91 9152987821\n"
"📞 *Vandrevala Foundation* – 1860 266 2345 or 1800 233 3330\n\n"
"🌍 **International Helplines**\n"
"📞 *Lifeline (USA)* – 988\n"
"📞 *Samaritans (UK)* – 116 123\n"
"📞 *Lifeline (Australia)* – 13 11 14\n\n"
"You are not alone. There are people who care and want to help 💚"
)
# Emotions dictionary removed - ChatGPT now handles all responses naturally
# Functions
def set_personal_info(name, age, gender, language, Guardian_info):
user_info.update({"name": name, "age": age, "gender": gender, "language": language, "Guardian_info": Guardian_info,})
return gr.update(visible=True), f"✅ Welcome {name}! Preferences saved."
def show_personal_data():
today = datetime.date.today().strftime("%Y-%m-%d (%A)")
return f"📅 {today}\n👤 Name: {user_info['name']}\n🎂 Age: {user_info['age']}\n♀ Gender: {user_info['gender']}\n🌐 Language: {user_info['language']}\n Guardian_info: {user_info['Guardian_info']}"
def generate_reply(input_text):
text = input_text.lower()
# Check for harmful keywords with word boundaries - crisis intervention
for word in harmful_keywords:
pattern = r'\b' + re.escape(word) + r'\b'
if re.search(pattern, text):
return harmful_response
# Use OpenAI ChatGPT for natural conversation
try:
response = client.chat.completions.create(
model="gpt-3.5-turbo", # or "gpt-4" for better responses
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": input_text}
],
temperature=0.7,
max_tokens=200
)
return response.choices[0].message.content
except Exception as e:
return f"I'm having trouble connecting right now, but I'm here to listen. Can you tell me more about what you're feeling?"
def chat_function(audio_input, text_input):
user_text = text_input.strip()
if not user_text:
return "Please type something or try again.", None
try:
reply = generate_reply(user_text)
chat_history.append({"user": user_text, "bot": reply})
lang_code = lang_codes.get(user_info["language"], "en")
tts = gTTS(reply, lang=lang_code)
audio_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
tts.save(audio_file.name)
return reply, audio_file.name
except Exception as e:
error_msg = f"Something went wrong: {str(e)}"
return error_msg, None
def get_chat_history():
if not chat_history:
return "No conversations yet."
return "\n\n".join([f"You: {c['user']}\nBot: {c['bot']}" for c in chat_history])
def save_journal(entry):
if not entry.strip():
return "⚠️ Please write something before saving."
try:
journal_entries.append(entry)
with open("journal.json", "w") as f:
json.dump(journal_entries, f, indent=2)
return "✅ Journal entry saved successfully!"
except Exception as e:
return f"❌ Error saving journal: {str(e)}"
def show_journal_history():
return "\n---\n".join(journal_entries) if journal_entries else "No journal entries yet."
def next_calm_tip():
tip = calm_tips[tip_index["calm"] % len(calm_tips)]
tip_index["calm"] += 1
return tip
def next_study_tip():
tip = study_tips[tip_index["study"] % len(study_tips)]
tip_index["study"] += 1
return tip
# -------------- Gradio App --------------
with gr.Blocks() as app:
welcome_screen = gr.Column(visible=True)
full_app = gr.Tabs(visible=False)
with welcome_screen:
gr.HTML("""
<style>
#main-title {
text-align: center;
font-size: 2.5em;
}
#subtitle {
text-align: center;
font-size: 1.2em;
color: #ccc;
margin-bottom: 30px;
}
#start-btn {
background-color: #ff69b4;
color: white;
font-weight: bold;
border: none;
border-radius: 10px;
padding: 14px 45px;
font-size: 1.1em;
cursor: pointer;
display: block;
margin: 0 auto;
}
#start-btn:hover {
background-color: #ff85c1;
}
</style>
""")
gr.Markdown("<h1 id='main-title'>StrongMind Therapist 2.0</h1>")
gr.Markdown("<h3 id='subtitle'>Your peaceful space to talk, journal, and focus.</h3>")
start_button = gr.Button("🌸 Get Started", elem_id="start-btn")
def start_app():
return gr.update(visible=False), gr.update(visible=True)
start_button.click(start_app, outputs=[welcome_screen, full_app])
with full_app:
with gr.Tab("1️⃣ Personal Info"):
name = gr.Textbox(label="Name")
age = gr.Textbox(label="Age")
gender = gr.Dropdown(["Male", "Female", "Other"], label="Gender")
language = gr.Dropdown(list(lang_codes.keys()), label="Preferred Language")
Guardian_info = gr.Textbox(label="Guardian information")
btn = gr.Button("Save Info")
popup = gr.Markdown(visible=False, elem_classes="alert-box")
btn.click(set_personal_info, [name, age, gender, language,Guardian_info], [popup, popup])
with gr.Tab("2️⃣ Personal Info Data"):
show = gr.Button("Show My Info")
info_display = gr.Textbox(lines=6)
show.click(show_personal_data, outputs=info_display)
with gr.Tab("3️⃣ Chat"):
gr.Markdown("🗣️ Describe your day in one word.")
audio_input = gr.Audio(type="filepath", label="🎧 Say something")
text_input = gr.Textbox(label="⌨️ Or type here")
send = gr.Button("Send")
bot_reply = gr.Textbox(label="🧠 Therapist")
voice = gr.Audio(label="🔊 Voice Reply")
send.click(chat_function, [audio_input, text_input], [bot_reply, voice])
with gr.Tab("4️⃣ Chat History"):
show_history = gr.Button("📜 Show Chats")
chat_out = gr.Textbox(lines=20, label="History")
show_history.click(get_chat_history, outputs=chat_out)
with gr.Tab("5️⃣ Journal"):
journal_input = gr.Textbox(lines=6, label="Write your thoughts")
save = gr.Button("Save")
journal_status = gr.Textbox()
save.click(save_journal, journal_input, journal_status)
with gr.Tab("6️⃣ Journal History"):
view = gr.Button("View Past Entries")
past = gr.Textbox(lines=15, label="Previous Journals")
view.click(show_journal_history, outputs=past)
with gr.Tab("7️⃣ Calm Space"):
tip_btn = gr.Button("🌿 Give Me a Calm Tip")
calm_text = gr.Textbox()
tip_btn.click(next_calm_tip, outputs=calm_text)
with gr.Tab("8️⃣ Study Tips"):
tip_btn2 = gr.Button("📚 Study Tip")
study_text = gr.Textbox()
tip_btn2.click(next_study_tip, outputs=study_text)
with gr.Tab("9️⃣ Pomodoro"):
gr.Markdown("⏱️ Use 25 min study + 5 min break cycles.\n(For real timer, use front-end JavaScript or Android timers)")
with gr.Tab("💠 Games"):
gr.Markdown("🎮 Play from the game portal below:")
gr.HTML(
'''
<iframe
src="https://www.onlinegames.io/embed/portal/"
width="100%"
height="600"
frameborder="0"
allowfullscreen>
</iframe> ''' )
if __name__ == "__main__":
app.launch()