Spaces:
Sleeping
Sleeping
File size: 9,949 Bytes
d0a9c6c 94c17a8 a6d0898 d573b9d ae86b01 54338b5 b5416c6 a9d4cd3 3f212e7 f0434c5 ae86b01 3f212e7 ae86b01 3f212e7 ae86b01 523a9dd a5285cf d0a9c6c d3288d3 9d87ee0 b780a7e 9d87ee0 d3288d3 b780a7e d3288d3 b780a7e 94c17a8 7458894 4bfa774 7458894 4bfa774 11044d5 4bfa774 11044d5 4bfa774 11044d5 4bfa774 11044d5 4bfa774 61f1871 4bfa774 88af390 792b8e2 88af390 ec61c05 88af390 ec61c05 61f1871 88af390 792b8e2 88af390 792b8e2 5173860 792b8e2 5173860 88af390 61f1871 88af390 61f1871 5173860 88af390 a6d0898 61f1871 d573b9d 110f8a7 61f1871 308f112 61f1871 308f112 907f8ac 308f112 61f1871 a6d0898 61f1871 a6d0898 61f1871 bd25b5c d7cd3e5 a6d0898 d7cd3e5 a6d0898 510fc4d d7cd3e5 a6d0898 61f1871 a6d0898 d7cd3e5 a6d0898 308f112 6d40481 a6d0898 6d40481 d7cd3e5 | 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 144 145 146 147 148 149 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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | import gradio as gr
from huggingface_hub import InferenceClient
from sentence_transformers import SentenceTransformer
import torch
from datetime import datetime
css = """
body, .gradio-container {
background: linear-gradient(
135deg,
#83c1ec 0%,
#a9b8ef 50%,
#c4abf2 100%
);
backdrop-filter: blur(20px);
}
.gr-block, .gr-panel, .gr-box, .gr-group {
background-color: #0a1a3d
border-radius: 12px
border: 1px solid #132a5e
}
button, .gr-button {
background-color: #7b2cbf
color: white
border-radius: 15px
transition: 0.3s;
}
button:hover, .gr-button:hover {
background-color: #9d4edd
transform: scale(1.05);
}
"""
journal_storage = [] # now holds dicts: {"category", "text", "timestamp"}
JOURNAL_CATEGORIES = [
"Daily Life", "Travel", "School", "Friends & Family",
"Gratitude", "Goals", "Feelings", "Other",
]
client = InferenceClient("Qwen/Qwen2.5-7B-Instruct")
# Open the knowledge base file in read mode with UTF-8 encoding
with open("UMATTER KNOWLEDGE BASE.txt", "r", encoding="utf-8") as file:
# Read the entire contents of thfile and store it in a variable
knowledge_base_text = file.read()
def preprocess_text(text):
# Strip extra whitespace from the beginning and the end of the text
cleaned_text = text.strip()
# Split the cleaned_text by every newline character (\n)
chunks = cleaned_text.split(". ")
# Create an empty list to store cleaned chunks
cleaned_chunks = []
# Write your for-in loop below to clean each chunk and add it to the cleaned_chunks list
for chunk in chunks:
stripped_chunk = chunk.strip()
if len(stripped_chunk) > 0:
cleaned_chunks.append(stripped_chunk)
# Return the cleaned_chunks
return cleaned_chunks
# Call the preprocess_text function and store the result in a cleaned_chunks variable
cleaned_chunks = preprocess_text(knowledge_base_text) # Complete this line
#load the pre-trained embelling model that converts text to vectors
model=SentenceTransformer('all-MiniLM-L6-v2')
def create_embeddings(text_chunks):
#convert each text chunk into vector embedding and store as a tensor
chunk_embeddings= model.encode(text_chunks, convert_to_tensor=True)
#return the chunk_embeddings
return chunk_embeddings
#call the create_embeddings function and store the result in a new chunk_embeddings variable
chunk_embeddings= create_embeddings(cleaned_chunks)
def get_top_chunks(query, chunk_embeddings, text_chunks):
# Convert the query text into a vector embedding
query_embedding = model.encode(query, convert_to_tensor=True)
# Normalize the query embedding to unit length
query_embedding_normalized = query_embedding / query_embedding.norm()
# Normalize all chunk embeddings
chunk_embeddings_normalized = chunk_embeddings / chunk_embeddings.norm(dim=1, keepdim=True)
# Calculate cosine similarity
similarities = torch.matmul(
chunk_embeddings_normalized,
query_embedding_normalized
)
# Find indices of top 3 chunks
top_indices = torch.topk(similarities, k=3).indices.tolist()
# Retrieve the top chunks
top_chunks = [text_chunks[idx] for idx in top_indices]
return top_chunks
def respond(message, history, country):
full_query = message + " " + country
context_chunks = get_top_chunks(full_query, chunk_embeddings, cleaned_chunks)
context_str = "\n".join(context_chunks)
system_prompt = f"""
You are UMatter, a mental wellness chatbot for users aged 13 to 25.
Your role is to provide support in a safe, calm and non-judgmental way.
You are not a therapist and must never diagnose mental health conditions.
When a user sends a message, first identify their emotional state from:
sadness, anger or frustration, loneliness, overwhelm, confusion, neutral.
Add a Disclaimer: *Disclaimer: This bot is NOT a therapist, it cannot understand emotions. Please seek human therapists but use this as a hub.
Use the following context if relevant:
{context_str}
and
{country}
"""
messages = [{"role": "system", "content": system_prompt}]
for turn in history:
if isinstance(turn, dict):
messages.append({"role": turn["role"], "content": turn["content"]})
else:
user_msg, bot_msg = turn
if user_msg:
messages.append({"role": "user", "content": user_msg})
if bot_msg:
messages.append({"role": "assistant", "content": bot_msg})
messages.append({"role": "user", "content": message})
response = ""
for msg in client.chat_completion(
messages,
max_tokens=512,
stream=True,
temperature=0.7,
top_p=0.9,
):
token = msg.choices[0].delta.content
if token:
response += token
yield response
def get_all_categories():
cats = set(JOURNAL_CATEGORIES)
for entry in journal_storage:
cats.add(entry["category"])
return ["All"] + sorted(cats)
def build_choices(filter_category="All"):
choices = []
for i, entry in enumerate(journal_storage):
if filter_category == "All" or entry["category"] == filter_category:
preview = entry["text"][:30].replace("\n", " ")
label = f"[{entry['category']}] {entry['timestamp']} β {preview}β¦"
choices.append((label, i))
return choices
with gr.Blocks(css=css) as demo:
gr.Image(value="UMatter.png", show_label=False, container=False, height=250)
gr.Markdown("# π UMatter - Youth Mental Health Support Hub")
with gr.Tabs():
with gr.TabItem("π¬ Support Chat"):
country_dropdown = gr.Dropdown(
choices=[
"United States",
"India",
"Canada",
"United Kingdom",
"Australia",
"Germany",
"France",
"Japan",
"Mexico",
"Brazil",
"South Korea"
],
value="United States",
label="Select Your Country"
)
gr.ChatInterface(
fn=respond,
additional_inputs=[country_dropdown],
title="UMatter Chat",
description="Talk to me about anything mental health π"
)
# Tab 2: Our brand new private journal space
with gr.TabItem("π My Private Journal"):
gr.Markdown("### π Your Secure Personal Space")
with gr.Row():
# Left Column: Writing entries
with gr.Column(scale=2):
journal_input = gr.Textbox(
label="Write your thoughts here...",
placeholder="How was your day? What's on your mind?",
lines=10
)
category_dropdown = gr.Dropdown(
choices=JOURNAL_CATEGORIES,
value="Daily Life",
label="π Category",
info="Pick one or type your own",
allow_custom_value=True
)
save_btn = gr.Button("πΎ Save Entry", variant="primary")
status_output = gr.Markdown("") # To show "Saved successfully!"
# Right Column: Viewing past entries
with gr.Column(scale=1):
gr.Markdown("#### π Past Reflections")
filter_dropdown = gr.Dropdown(
choices=["All"] + JOURNAL_CATEGORIES,
value="All",
label="π Filter by category"
)
history_dropdown = gr.Dropdown(
choices=[],
label="Select a previous entry",
interactive=True
)
view_btn = gr.Button("π View Selected")
def save_journal_entry(text, category):
if not text.strip():
return gr.update(), gr.update(value="β οΈ Cannot save an empty entry!"), gr.update(), gr.update()
category = (category or "Other").strip() or "Other"
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M")
journal_storage.append({"category": category, "text": text.strip(), "timestamp": timestamp})
return (
gr.update(value=""),
gr.update(value=f"β
Entry saved under **{category}**!"),
gr.update(choices=build_choices("All"), value=None),
gr.update(choices=get_all_categories(), value="All"),
)
def filter_entries(filter_category):
return gr.update(choices=build_choices(filter_category), value=None)
def view_journal_entry(selected_index):
if selected_index is None:
return gr.update()
return gr.update(value=journal_storage[selected_index]["text"])
save_btn.click(
fn=save_journal_entry,
inputs=[journal_input, category_dropdown],
outputs=[journal_input, status_output, history_dropdown, filter_dropdown]
)
filter_dropdown.change(
fn=filter_entries,
inputs=filter_dropdown,
outputs=history_dropdown
)
view_btn.click(
fn=view_journal_entry,
inputs=history_dropdown,
outputs=journal_input
)
demo.launch(debug=True) |