Chatbot_v2 / app.py
Pant0x's picture
Upload app.py
7f0c43e verified
import gradio as gr
from huggingface_hub import InferenceClient
import random
import re
# ✅ Allowed mental health keywords (EN + AR + transliterated Arabic)
MENTAL_KEYWORDS = [
# English
"depression", "depressed", "anxiety", "anxious", "panic", "stress", "sad", "lonely",
"trauma", "mental", "therapy", "therapist", "counselor", "mood", "overwhelmed", "anger",
"fear", "worry", "self-esteem", "confidence", "motivation", "relationship", "cope", "coping",
"relax", "calm", "sleep", "emotion", "feeling", "feel", "thoughts", "help", "life", "advice",
"unmotivated", "lost", "hopeless", "tired", "burnout", "cry", "hurt", "love", "breakup",
"friend", "family", "alone", "heartbroken", "scared", "fearful",
# Transliterated Arabic
"ana", "zahqan", "daye2", "ha2t", "mota3ab", "mota3eb", "za3lan", "malo", "khalni", "mash3or",
"bakhaf", "w7ed", "msh 3aref", "mash fahem", "malish", "3ayez", "ayez", "7azeen", "mdaye2",
# Arabic
"حزين", "تعبان", "قلق", "خايف", "وحدة", "ضيق", "توتر", "زعلان", "اكتئاب", "علاج",
"مشاعر", "مضغوط", "قلقان", "وحدي", "مش مبسوط", "زهقان", "ضايق", "تعب", "مش مرتاح",
]
# ✅ Off-topic keywords (EN + AR)
OFF_TOPIC = [
# English
"recipe", "song", "music", "lyrics", "joke", "funny", "laugh", "code", "python", "program",
"game", "food", "cook", "movie", "film", "series", "sport", "football", "instagram",
"tiktok", "money", "business", "crypto", "ai", "computer",
# Arabic
"نكتة", "ضحك", "اغنية", "اغاني", "طبخ", "اكل", "فيلم", "مسلسل", "كورة", "رياضة",
"بيزنس", "فلوس", "العاب", "لعبة", "كود", "برمجة", "ذكاء اصطناعي"
]
# ✅ Random natural off-topic responses
OFF_TOPIC_RESPONSES = [
"I'm here to help with emotional and mental well-being. Let's focus on how you're feeling, coping, or managing your emotions today.",
"I specialize in mental and emotional health conversations. Tell me what’s been on your mind lately.",
"Let’s bring it back to how you’ve been feeling — I’m here to help you talk through emotions, stress, or challenges.",
"My goal is to support your mental health. How have things been emotionally for you lately?",
"I’m here for emotional and mental support only. What’s been bothering you recently?",
"Let's focus on your thoughts and feelings — I can help you process or manage them better.",
"It sounds like you might be going off-topic. Can we talk about how you’ve been feeling instead?",
"Let’s keep this space focused on your emotions and well-being. What’s been heavy on your mind lately?",
]
# ✅ Detect Arabic characters
def contains_arabic(text: str) -> bool:
return bool(re.search(r"[\u0600-\u06FF]", text))
# ✅ Function to check if input is related to mental health
def is_mental_health_related(text: str) -> bool:
text_lower = text.lower()
has_arabic = contains_arabic(text_lower)
# If message includes off-topic Arabic or English terms → block it
if any(word in text_lower for word in OFF_TOPIC):
return False
# If it has mental-related Arabic/English → allow
if any(word in text_lower for word in MENTAL_KEYWORDS):
return True
# If purely Arabic but not off-topic → assume emotional (allow)
if has_arabic:
return True
# Default fallback
return False
# ✅ Main response function
def respond(
message,
history: list[dict[str, str]],
system_message,
max_tokens,
temperature,
top_p,
hf_token: gr.OAuthToken,
):
if not is_mental_health_related(message):
yield random.choice(OFF_TOPIC_RESPONSES)
return
locked_system_message = (
"You are a licensed mental health therapy assistant. "
"You respond with empathy, emotional intelligence, and a therapeutic tone. "
"Never answer questions unrelated to emotional or mental wellness, even if they are in another language."
)
client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
messages = [{"role": "system", "content": locked_system_message}]
messages.extend(history)
messages.append({"role": "user", "content": message})
response = ""
for message in client.chat_completion(
messages,
max_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
):
choices = message.choices
token = ""
if len(choices) and choices[0].delta.content:
token = choices[0].delta.content
response += token
yield response
# ✅ Gradio interface setup
chatbot = gr.ChatInterface(
respond,
type="messages",
additional_inputs=[
gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.95,
step=0.05,
label="Top-p (nucleus sampling)",
),
],
)
with gr.Blocks() as demo:
with gr.Sidebar():
gr.LoginButton()
chatbot.render()
if __name__ == "__main__":
demo.launch()