Spaces:
Sleeping
Sleeping
| 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) |