|
import streamlit as st |
|
import os |
|
import json |
|
import requests |
|
import nltk |
|
from nltk.sentiment import SentimentIntensityAnalyzer |
|
from transformers import BlenderbotTokenizer, BlenderbotForConditionalGeneration |
|
from dotenv import load_dotenv |
|
import time |
|
|
|
|
|
load_dotenv() |
|
groq_api_key = os.getenv("GROQ_API_KEY") |
|
|
|
def run_mental_health(): |
|
|
|
try: |
|
nltk.data.find('vader_lexicon') |
|
except LookupError: |
|
nltk.download('vader_lexicon') |
|
|
|
|
|
if 'conversation' not in st.session_state: |
|
st.session_state.conversation = [] |
|
if 'therapy_state' not in st.session_state: |
|
st.session_state.therapy_state = "initial" |
|
if 'mental_health_scores' not in st.session_state: |
|
st.session_state.mental_health_scores = { |
|
"anxiety": 0, |
|
"depression": 0, |
|
"stress": 0, |
|
"loneliness": 0, |
|
"grief": 0, |
|
"relationship_issues": 0, |
|
"self_esteem": 0, |
|
"trauma": 0 |
|
} |
|
if 'assessment_progress' not in st.session_state: |
|
st.session_state.assessment_progress = 0 |
|
if 'current_question' not in st.session_state: |
|
st.session_state.current_question = None |
|
if 'current_options' not in st.session_state: |
|
st.session_state.current_options = None |
|
if 'llm_service' not in st.session_state: |
|
st.session_state.llm_service = "llama3" |
|
if 'user_submitted' not in st.session_state: |
|
st.session_state.user_submitted = False |
|
if 'severity_rating' not in st.session_state: |
|
st.session_state.severity_rating = None |
|
if 'sentiment_analysis' not in st.session_state: |
|
st.session_state.sentiment_analysis = [] |
|
if 'other_selected' not in st.session_state: |
|
st.session_state.other_selected = False |
|
if 'response_delay' not in st.session_state: |
|
st.session_state.response_delay = False |
|
|
|
|
|
@st.cache_resource |
|
def load_blenderbot_model(): |
|
tokenizer = BlenderbotTokenizer.from_pretrained("facebook/blenderbot-400M-distill") |
|
model = BlenderbotForConditionalGeneration.from_pretrained("facebook/blenderbot-400M-distill") |
|
return tokenizer, model |
|
|
|
|
|
@st.cache_resource |
|
def load_sentiment_analyzer(): |
|
return SentimentIntensityAnalyzer() |
|
|
|
|
|
def use_llama3_api(prompt, max_tokens=1000): |
|
headers = { |
|
"Authorization": f"Bearer {groq_api_key}", |
|
"Content-Type": "application/json" |
|
} |
|
|
|
data = { |
|
"model": "llama3-70b-8192", |
|
"messages": [{"role": "user", "content": prompt}], |
|
"max_tokens": max_tokens, |
|
"temperature": 0.7 |
|
} |
|
|
|
try: |
|
response = requests.post( |
|
"https://api.groq.com/openai/v1/chat/completions", |
|
headers=headers, |
|
json=data, |
|
timeout=10 |
|
) |
|
|
|
if response.status_code == 200: |
|
return response.json()["choices"][0]["message"]["content"] |
|
else: |
|
st.error(f"Error from Groq API: {response.text}") |
|
return "I'm having trouble connecting. Let's continue our conversation more simply." |
|
except Exception as e: |
|
st.error(f"Exception when calling Groq API: {str(e)}") |
|
return "I encountered an error when trying to respond. Let me try a simpler approach." |
|
|
|
|
|
def use_blenderbot(input_text, tokenizer, model): |
|
try: |
|
inputs = tokenizer([input_text], return_tensors="pt") |
|
reply_ids = model.generate(**inputs, max_length=100) |
|
response = tokenizer.batch_decode(reply_ids, skip_special_tokens=True)[0] |
|
return response |
|
except Exception as e: |
|
st.error(f"Error from Blenderbot: {str(e)}") |
|
return "I'm having trouble understanding that. Could you rephrase or tell me more?" |
|
|
|
|
|
def handle_option_select(): |
|
selected_option = st.session_state.selected_option |
|
if selected_option: |
|
|
|
if selected_option == "Other": |
|
st.session_state.other_selected = True |
|
else: |
|
|
|
st.session_state.conversation.append(selected_option) |
|
|
|
|
|
update_mental_health_scores(selected_option) |
|
|
|
st.session_state.user_submitted = True |
|
st.session_state.other_selected = False |
|
|
|
|
|
|
|
|
|
def handle_custom_submit(): |
|
custom_input = st.session_state.custom_input |
|
if custom_input: |
|
|
|
st.session_state.conversation.append(custom_input) |
|
|
|
|
|
update_mental_health_scores(custom_input) |
|
|
|
st.session_state.user_submitted = True |
|
st.session_state.custom_input = "" |
|
st.session_state.other_selected = False |
|
|
|
|
|
def update_mental_health_scores(user_input): |
|
|
|
sia = load_sentiment_analyzer() |
|
sentiment = sia.polarity_scores(user_input) |
|
|
|
|
|
st.session_state.sentiment_analysis.append({ |
|
"text": user_input, |
|
"sentiment": sentiment, |
|
"timestamp": time.time() |
|
}) |
|
|
|
|
|
mental_health_keywords = { |
|
"anxiety": ["anxious", "nervous", "worry", "panic", "fear", "stress", "tense", "overwhelm", "anxiousness", "uneasy"], |
|
"depression": ["sad", "depress", "hopeless", "meaningless", "empty", "tired", "exhausted", "unmotivated", "worthless", "guilt"], |
|
"stress": ["stress", "pressure", "overwhelm", "burden", "strain", "tension", "burnout", "overworked", "deadline", "rush"], |
|
"loneliness": ["lonely", "alone", "isolate", "disconnect", "abandoned", "reject", "outcast", "friendless", "solitary", "unloved"], |
|
"grief": ["grief", "loss", "death", "miss", "mourn", "gone", "passed away", "bereavement", "widow", "funeral"], |
|
"relationship_issues": ["relationship", "partner", "marriage", "divorce", "argument", "fight", "breakup", "separation", "trust", "jealous"], |
|
"self_esteem": ["confidence", "worth", "value", "failure", "ugly", "stupid", "incompetent", "loser", "undeserving", "inadequate"], |
|
"trauma": ["trauma", "abuse", "assault", "accident", "violence", "nightmare", "flashback", "ptsd", "terrify", "horrific"] |
|
} |
|
|
|
|
|
user_input_lower = user_input.lower() |
|
|
|
for issue, keywords in mental_health_keywords.items(): |
|
for keyword in keywords: |
|
if keyword in user_input_lower: |
|
|
|
increase = 1 + (1 - sentiment["compound"]) * 0.5 |
|
if sentiment["compound"] < -0.2: |
|
increase *= 1.5 |
|
|
|
st.session_state.mental_health_scores[issue] += increase |
|
|
|
|
|
if len(user_input) > 15: |
|
try: |
|
assess_prompt = f""" |
|
Analyze this statement for signs of mental health issues. Give a rating from 0-5 |
|
(0 = not present, 5 = severe) for each of these categories: |
|
- Anxiety |
|
- Depression |
|
- Stress |
|
- Loneliness |
|
- Grief |
|
- Relationship issues |
|
- Self-esteem issues |
|
- Trauma indicators |
|
|
|
Return ONLY the numerical ratings in JSON format like this: |
|
{{ |
|
"anxiety": X, |
|
"depression": X, |
|
"stress": X, |
|
"loneliness": X, |
|
"grief": X, |
|
"relationship_issues": X, |
|
"self_esteem": X, |
|
"trauma": X |
|
}} |
|
|
|
The statement: "{user_input}" |
|
""" |
|
|
|
llm_assessment = use_llama3_api(assess_prompt, max_tokens=100) |
|
|
|
|
|
try: |
|
json_start = llm_assessment.find('{') |
|
json_end = llm_assessment.rfind('}') + 1 |
|
if json_start >= 0 and json_end > json_start: |
|
json_str = llm_assessment[json_start:json_end] |
|
llm_scores = json.loads(json_str) |
|
|
|
|
|
for issue, score in llm_scores.items(): |
|
if issue in st.session_state.mental_health_scores: |
|
|
|
st.session_state.mental_health_scores[issue] += score * 0.4 |
|
except: |
|
|
|
pass |
|
except: |
|
|
|
pass |
|
|
|
|
|
def generate_next_question_with_options(conversation_history, mental_health_scores): |
|
|
|
scores_summary = ", ".join([f"{issue}: {score:.1f}" for issue, score in mental_health_scores.items()]) |
|
|
|
previous_convo = "" |
|
if conversation_history: |
|
previous_convo = "\nPrevious conversation: " + " ".join([f"{'User: ' if i%2==1 else 'Therapist: '}{msg}" for i, msg in enumerate(conversation_history)]) |
|
|
|
prompt = f"""Act as a supportive mental health therapist. You're having a conversation with someone seeking help. |
|
Current mental health indicators: {scores_summary} |
|
{previous_convo} |
|
|
|
Based on this information, what's the most important therapeutic question to ask next? |
|
Also provide 5 likely response options the person might give. |
|
|
|
Format your response as a JSON object like this: |
|
{{ |
|
"question": "Your therapeutic question here?", |
|
"options": [ |
|
"Possible response 1", |
|
"Possible response 2", |
|
"Possible response 3", |
|
"Possible response 4", |
|
"Possible response 5" |
|
] |
|
}} |
|
|
|
Ensure your question is empathetic, supportive, and helps explore the person's feelings or situation further. |
|
Make the options specific and relevant to potential mental health concerns.""" |
|
|
|
try: |
|
response = use_llama3_api(prompt, max_tokens=500) |
|
|
|
|
|
try: |
|
|
|
json_start = response.find('{') |
|
json_end = response.rfind('}') + 1 |
|
if json_start >= 0 and json_end > json_start: |
|
json_str = response[json_start:json_end] |
|
result = json.loads(json_str) |
|
|
|
|
|
if "question" in result and "options" in result: |
|
|
|
if "Other" not in result["options"]: |
|
result["options"].append("Other") |
|
return result["question"], result["options"] |
|
|
|
except json.JSONDecodeError: |
|
|
|
return "How are you feeling right now?", [ |
|
"I'm feeling anxious", |
|
"I'm feeling sad", |
|
"I'm feeling overwhelmed", |
|
"I'm feeling okay", |
|
"I don't know how I feel", |
|
"Other" |
|
] |
|
|
|
except Exception as e: |
|
st.error(f"Error generating question: {str(e)}") |
|
|
|
|
|
return "Would you like to tell me more about what's on your mind?", [ |
|
"Yes, I need to talk", |
|
"I'm not sure where to start", |
|
"I don't think it will help", |
|
"I'm feeling too overwhelmed", |
|
"I'd rather listen to advice", |
|
"Other" |
|
] |
|
|
|
|
|
def generate_therapeutic_response(user_input, conversation_history, mental_health_scores): |
|
|
|
if st.session_state.llm_service == "blenderbot": |
|
tokenizer, model = load_blenderbot_model() |
|
return use_blenderbot(user_input, tokenizer, model) |
|
|
|
|
|
scores_summary = ", ".join([f"{issue}: {score:.1f}" for issue, score in mental_health_scores.items()]) |
|
|
|
|
|
recent_convo = "" |
|
if len(conversation_history) > 0: |
|
|
|
recent_messages = conversation_history[-10:] if len(conversation_history) >= 10 else conversation_history |
|
recent_convo = "\n".join([f"{'User: ' if i%2==1 else 'Therapist: '}{msg}" for i, msg in enumerate(recent_messages)]) |
|
|
|
|
|
top_issues = sorted(mental_health_scores.items(), key=lambda x: x[1], reverse=True)[:3] |
|
top_issues_str = ", ".join([f"{issue}" for issue, score in top_issues if score > 1]) |
|
focus_areas = f"Potential areas of focus: {top_issues_str}" if top_issues_str else "No clear mental health concerns identified yet." |
|
|
|
prompt = f"""Act as an empathetic, supportive mental health therapist using person-centered therapy approaches. |
|
You're having a conversation with someone seeking help. |
|
|
|
Current mental health indicators: {scores_summary} |
|
{focus_areas} |
|
|
|
Recent conversation: |
|
{recent_convo} |
|
|
|
User's most recent message: "{user_input}" |
|
|
|
Provide a thoughtful, validating response that: |
|
1. Shows you understand their feelings |
|
2. Offers support without judgment |
|
3. Asks open-ended questions to explore their concerns deeper |
|
4. Avoids giving simplistic advice or dismissing feelings |
|
5. Uses techniques like reflective listening and validation |
|
|
|
Keep your response conversational, warm and natural - like a supportive friend would talk. |
|
Limit your response to 3-4 sentences to maintain engagement.""" |
|
|
|
try: |
|
return use_llama3_api(prompt, max_tokens=250) |
|
except Exception as e: |
|
st.error(f"Error generating response: {str(e)}") |
|
return "I'm here to listen. Would you like to tell me more about what you're experiencing?" |
|
|
|
|
|
def assessment_complete(mental_health_scores, conversation_length): |
|
|
|
|
|
|
|
|
|
significant_issues = sum(1 for score in mental_health_scores.values() if score > 2) |
|
|
|
|
|
|
|
|
|
return (conversation_length >= 10 and significant_issues >= 1) or conversation_length >= 20 |
|
|
|
|
|
def generate_assessment_summary(conversation_history, mental_health_scores): |
|
|
|
significant_scores = {issue: score for issue, score in mental_health_scores.items() if score > 1} |
|
|
|
|
|
sorted_scores = sorted(significant_scores.items(), key=lambda x: x[1], reverse=True) |
|
|
|
|
|
scores_text = "" |
|
for issue, score in sorted_scores: |
|
|
|
severity = "mild" |
|
if score > 5: |
|
severity = "moderate" |
|
if score > 8: |
|
severity = "significant" |
|
if score > 12: |
|
severity = "severe" |
|
|
|
formatted_issue = issue.replace("_", " ").title() |
|
scores_text += f"- {formatted_issue}: {severity} (score: {score:.1f})\n" |
|
|
|
if not scores_text: |
|
scores_text = "- No significant mental health concerns detected\n" |
|
|
|
|
|
sentiment_data = st.session_state.sentiment_analysis |
|
|
|
|
|
if sentiment_data: |
|
most_negative = min(sentiment_data, key=lambda x: x["sentiment"]["compound"]) |
|
most_positive = max(sentiment_data, key=lambda x: x["sentiment"]["compound"]) |
|
|
|
significant_statements = f""" |
|
Most concerning statement: "{most_negative['text']}" |
|
Most positive statement: "{most_positive['text']}" |
|
""" |
|
else: |
|
significant_statements = "No significant statements analyzed." |
|
|
|
|
|
prompt = f"""As a mental health professional, create a supportive therapeutic assessment summary |
|
based on the following information from a conversation with a client: |
|
|
|
Mental health indicators: |
|
{scores_text} |
|
|
|
{significant_statements} |
|
|
|
Create a compassionate assessment summary that includes: |
|
1. The primary mental health concerns identified (if any) |
|
2. Supportive validation of the person's experiences |
|
3. General self-care recommendations |
|
4. When professional help would be recommended |
|
5. A hopeful message about the possibility of improvement |
|
|
|
Your assessment should be non-judgmental, respectful, and empowering. Focus on the person's |
|
strengths as well as challenges. Make it clear this is NOT a clinical diagnosis.""" |
|
|
|
try: |
|
assessment = use_llama3_api(prompt, max_tokens=500) |
|
|
|
|
|
severity = "Low" |
|
highest_score = max(mental_health_scores.values()) if mental_health_scores else 0 |
|
if highest_score > 8: |
|
severity = "High" |
|
elif highest_score > 4: |
|
severity = "Moderate" |
|
|
|
|
|
assessment += "\n\n[Note: This is an AI-generated assessment for educational purposes only and should not replace professional mental health advice.]" |
|
|
|
return assessment, severity |
|
except Exception as e: |
|
st.error(f"Error generating assessment: {str(e)}") |
|
return "Unable to generate a complete assessment at this time. Please consider speaking with a mental health professional for personalized support.", "Unknown" |
|
|
|
|
|
def generate_resources(mental_health_scores): |
|
|
|
top_concerns = sorted(mental_health_scores.items(), key=lambda x: x[1], reverse=True)[:3] |
|
top_concerns = [concern for concern, score in top_concerns if score > 1] |
|
|
|
if not top_concerns: |
|
top_concerns = ["general_wellbeing"] |
|
|
|
concerns_text = ", ".join(top_concerns) |
|
|
|
prompt = f"""Create a list of helpful resources for someone dealing with these mental health concerns: {concerns_text}. |
|
|
|
Include: |
|
1. Three self-help techniques they can try immediately |
|
2. Three types of professionals who might help with these concerns |
|
3. Two reputable organizations or hotlines that provide support |
|
4. Two recommended books or workbooks that address these concerns |
|
|
|
Format your response with clear headings and brief explanations. Focus on practical, evidence-based resources.""" |
|
|
|
try: |
|
return use_llama3_api(prompt, max_tokens=400) |
|
except: |
|
|
|
return """ |
|
## Helpful Resources |
|
|
|
### Self-help Techniques |
|
- Practice deep breathing exercises (4-7-8 method) |
|
- Journal about your thoughts and feelings |
|
- Engage in regular physical activity |
|
|
|
### Professional Support |
|
- Licensed therapists or counselors |
|
- Psychiatrists (for medication evaluation) |
|
- Support groups for your specific concerns |
|
|
|
### Support Organizations |
|
- Crisis Text Line: Text HOME to 741741 |
|
- National Alliance on Mental Health (NAMI): 1-800-950-NAMI (6264) |
|
|
|
### Recommended Reading |
|
- "Feeling Good" by David Burns |
|
- "The Anxiety and Phobia Workbook" by Edmund Bourne |
|
|
|
Remember that seeking help is a sign of strength, not weakness. |
|
""" |
|
|
|
def display_interactive_summary(mental_health_scores, assessment, resources): |
|
"""Display an interactive, visually appealing summary of the therapy session""" |
|
|
|
st.markdown("## Your Wellness Summary") |
|
|
|
|
|
summary_tabs = st.tabs(["Overview", "Insights", "Recommendations", "Resources"]) |
|
|
|
with summary_tabs[0]: |
|
st.markdown("### How You're Feeling") |
|
|
|
|
|
col1, col2 = st.columns([3, 2]) |
|
|
|
with col1: |
|
|
|
sorted_scores = sorted(mental_health_scores.items(), key=lambda x: x[1], reverse=True) |
|
concerns = [item[0].replace("_", " ").title() for item in sorted_scores if item[1] > 1] |
|
scores = [item[1] for item in sorted_scores if item[1] > 1] |
|
|
|
|
|
if concerns: |
|
|
|
colors = [] |
|
for score in scores: |
|
if score > 8: |
|
colors.append("#FF4B4B") |
|
elif score > 4: |
|
colors.append("#FFA64B") |
|
else: |
|
colors.append("#4B9AFF") |
|
|
|
|
|
chart_data = { |
|
"concern": concerns, |
|
"score": scores |
|
} |
|
|
|
|
|
try: |
|
import altair as alt |
|
import pandas as pd |
|
|
|
chart_df = pd.DataFrame(chart_data) |
|
|
|
chart = alt.Chart(chart_df).mark_bar().encode( |
|
x='score', |
|
y=alt.Y('concern', sort='-x'), |
|
color=alt.Color('score', scale=alt.Scale(domain=[1, 5, 10], range=['#4B9AFF', '#FFA64B', '#FF4B4B'])), |
|
tooltip=['concern', 'score'] |
|
).properties( |
|
title='Mental Health Indicators', |
|
height=min(250, len(concerns) * 40) |
|
) |
|
|
|
st.altair_chart(chart, use_container_width=True) |
|
except: |
|
|
|
st.bar_chart(chart_data, x="concern", y="score", use_container_width=True) |
|
else: |
|
st.info("No significant mental health concerns were detected.") |
|
|
|
with col2: |
|
|
|
highest_score = max(mental_health_scores.values()) if mental_health_scores else 0 |
|
|
|
if highest_score > 8: |
|
wellness_status = "Needs Attention" |
|
status_color = "#FF4B4B" |
|
elif highest_score > 4: |
|
wellness_status = "Moderate Concern" |
|
status_color = "#FFA64B" |
|
else: |
|
wellness_status = "Doing Well" |
|
status_color = "#4CAF50" |
|
|
|
st.markdown(f""" |
|
<div style="padding: 20px; border-radius: 10px; background-color: {status_color}20; |
|
border: 1px solid {status_color}; text-align: center; margin-bottom: 20px;"> |
|
<h3 style="color: {status_color};">Current Status</h3> |
|
<h2 style="color: {status_color};">{wellness_status}</h2> |
|
</div> |
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown("### How are you feeling right now?") |
|
mood = st.select_slider( |
|
"My current mood is:", |
|
options=["Very Low", "Low", "Neutral", "Good", "Great"], |
|
value="Neutral" |
|
) |
|
|
|
|
|
if mood in ["Very Low", "Low"]: |
|
st.markdown("🌱 It's okay to not be okay. Small steps lead to big changes.") |
|
elif mood == "Neutral": |
|
st.markdown("✨ You're doing better than you think. Keep going!") |
|
else: |
|
st.markdown("🌟 That's wonderful! Celebrate your positive moments.") |
|
|
|
with summary_tabs[1]: |
|
st.markdown("### Understanding Your Experience") |
|
|
|
|
|
if assessment: |
|
|
|
import re |
|
|
|
|
|
concerns_match = re.search(r"Primary Mental Health Concerns:(.*?)(?:Validation|General Self-Care)", assessment, re.DOTALL) |
|
validation_match = re.search(r"Validation of Your Experiences:(.*?)(?:General Self-Care|When Professional)", assessment, re.DOTALL) |
|
|
|
|
|
def clean_text(text): |
|
|
|
text = text.replace("**", "") |
|
|
|
text = text.replace("[Client]", "friend").replace("Dear [Client],", "") |
|
text = text.replace("[Your Name]", "Your Well-Wisher") |
|
return text.strip() |
|
|
|
if concerns_match: |
|
st.markdown("#### Key Insights") |
|
concerns_text = clean_text(concerns_match.group(1).strip()) |
|
st.info(concerns_text) |
|
|
|
if validation_match: |
|
st.markdown("#### Reflections") |
|
validation_text = clean_text(validation_match.group(1).strip()) |
|
st.success(validation_text) |
|
|
|
|
|
with st.expander("See Complete Analysis"): |
|
|
|
cleaned_assessment = clean_text(assessment) |
|
|
|
cleaned_assessment = cleaned_assessment.replace("Dear friend,", "") |
|
cleaned_assessment = re.sub(r"Sincerely,.*$", "- Your Well-Wisher", cleaned_assessment) |
|
st.write(cleaned_assessment) |
|
else: |
|
st.warning("We couldn't generate a detailed assessment. Please speak with a mental health professional for personalized insights.") |
|
|
|
with summary_tabs[2]: |
|
st.markdown("### Suggested Next Steps") |
|
|
|
|
|
top_concerns = sorted(mental_health_scores.items(), key=lambda x: x[1], reverse=True)[:2] |
|
top_concerns = [concern for concern, score in top_concerns if score > 1] |
|
|
|
if not top_concerns: |
|
top_concerns = ["general_wellbeing"] |
|
|
|
|
|
recommendations = [] |
|
self_help_match = re.search(r"Self-Help Techniques(.*?)(?:Professionals Who Can Help|Support)", resources, re.DOTALL) if resources else None |
|
|
|
if self_help_match: |
|
techniques = re.findall(r"([\w\s]+):", self_help_match.group(1)) |
|
recommendations = [t.strip() for t in techniques if t.strip()] |
|
|
|
|
|
if not recommendations: |
|
recommendations = [ |
|
"Practice deep breathing exercises", |
|
"Connect with supportive friends or family", |
|
"Engage in physical activity", |
|
"Practice mindfulness meditation" |
|
] |
|
|
|
|
|
for i, rec in enumerate(recommendations[:3]): |
|
col1, col2 = st.columns([1, 20]) |
|
with col1: |
|
if st.checkbox("", key=f"rec_{i}", value=False): |
|
pass |
|
with col2: |
|
st.markdown(f"**{rec}**") |
|
|
|
|
|
st.markdown("#### Add Your Own Action") |
|
custom_action = st.text_input("What's one small step you can take today?") |
|
if custom_action: |
|
st.success(f"Great! Remember to try: {custom_action}") |
|
|
|
|
|
highest_score = max(mental_health_scores.values()) if mental_health_scores else 0 |
|
|
|
st.markdown("#### Professional Support") |
|
if highest_score > 8: |
|
st.warning("Based on our conversation, speaking with a mental health professional could be beneficial.") |
|
elif highest_score > 4: |
|
st.info("Consider reaching out to a mental health professional if you continue to experience these feelings.") |
|
else: |
|
st.success("Continue practicing self-care. Reach out to a professional if you notice your symptoms worsening.") |
|
|
|
with summary_tabs[3]: |
|
st.markdown("### Helpful Resources") |
|
|
|
|
|
resource_types = ["Crisis Support", "Professional Help", "Self-Help Books", "Mobile Apps", "Support Groups"] |
|
|
|
selected_resource = st.radio("What type of resources are you looking for?", resource_types) |
|
|
|
|
|
if selected_resource == "Crisis Support": |
|
st.markdown(""" |
|
#### Immediate Support |
|
- **Crisis Text Line**: Text HOME to 741741 (24/7 support) |
|
- **National Suicide Prevention Lifeline**: 988 or 1-800-273-8255 |
|
- **Emergency Services**: Call 911 if you're in immediate danger |
|
""") |
|
|
|
elif selected_resource == "Professional Help": |
|
st.markdown(""" |
|
#### Finding a Therapist |
|
- **Psychology Today**: Search for therapists in your area |
|
- **BetterHelp**: Online therapy platform |
|
- **Your insurance provider**: Many insurance plans cover mental health services |
|
""") |
|
|
|
st.markdown("#### Types of Mental Health Professionals") |
|
professionals = { |
|
"Therapist/Counselor": "Provides talk therapy and emotional support", |
|
"Psychiatrist": "Can prescribe medication and provide treatment", |
|
"Psychologist": "Specializes in psychological testing and therapy" |
|
} |
|
|
|
for prof, desc in professionals.items(): |
|
st.markdown(f"**{prof}**: {desc}") |
|
|
|
elif selected_resource == "Self-Help Books": |
|
|
|
books = [] |
|
books_match = re.search(r"Recommended (Books|Reading)(.*?)(?:\[Note|\Z)", resources, re.DOTALL) if resources else None |
|
|
|
if books_match: |
|
book_text = books_match.group(2) |
|
books = re.findall(r'"([^"]+)"', book_text) |
|
|
|
|
|
if not books: |
|
books = [ |
|
"Feeling Good by David Burns", |
|
"The Anxiety and Phobia Workbook by Edmund Bourne", |
|
"Man's Search for Meaning by Viktor Frankl" |
|
] |
|
|
|
for book in books: |
|
st.markdown(f"- **{book}**") |
|
|
|
elif selected_resource == "Mobile Apps": |
|
st.markdown(""" |
|
#### Helpful Mobile Apps |
|
- **Headspace**: Guided meditation and mindfulness exercises |
|
- **Calm**: Sleep, meditation and relaxation aid |
|
- **Woebot**: AI chatbot for mental health support |
|
- **Daylio**: Mood tracking journal |
|
- **Breathe2Relax**: Guided breathing exercises |
|
""") |
|
|
|
elif selected_resource == "Support Groups": |
|
st.markdown(""" |
|
#### Finding Support Groups |
|
- **NAMI**: National Alliance on Mental Illness offers support groups |
|
- **Mental Health America**: Provides peer support group resources |
|
- **Support Group Central**: Online support groups for various needs |
|
|
|
Remember that connecting with others who understand your experience can be incredibly healing. |
|
""") |
|
|
|
|
|
st.markdown("### Save These Resources") |
|
if st.button("Prepare Resources PDF"): |
|
st.success("Your personalized resource list has been prepared!") |
|
st.markdown(""" |
|
**Note:** In a full implementation, this would generate a downloadable PDF with |
|
all relevant resources customized to the user's needs. |
|
""") |
|
|
|
|
|
st.markdown("---") |
|
st.markdown(""" |
|
### Remember |
|
Your mental health journey is unique. Small steps forward still move you in the right direction. |
|
Each day is a new opportunity to prioritize your wellbeing. |
|
""") |
|
|
|
|
|
st.caption("This summary is for educational purposes only and should not replace professional mental health advice.") |
|
|
|
|
|
st.markdown("### What would you like to do next?") |
|
next_steps = st.columns(3) |
|
|
|
with next_steps[0]: |
|
if st.button("Continue Talking"): |
|
return "continue" |
|
|
|
with next_steps[1]: |
|
if st.button("Start New Session"): |
|
return "new" |
|
|
|
with next_steps[2]: |
|
if st.button("End Session"): |
|
return "end" |
|
|
|
return None |
|
|
|
st.title("AI Therapy Assistant") |
|
st.markdown("_This is a prototype for educational purposes only and should not be used as a replacement for professional mental health services._") |
|
|
|
def submit_initial_response(): |
|
if st.session_state.initial_response: |
|
|
|
st.session_state.conversation.append(initial_greeting) |
|
st.session_state.conversation.append(st.session_state.initial_response) |
|
|
|
|
|
update_mental_health_scores(st.session_state.initial_response) |
|
|
|
|
|
first_response = generate_therapeutic_response( |
|
st.session_state.initial_response, |
|
st.session_state.conversation, |
|
st.session_state.mental_health_scores |
|
) |
|
|
|
|
|
st.session_state.conversation.append(first_response) |
|
|
|
|
|
st.session_state.therapy_state = "therapy" |
|
|
|
|
|
question, options = generate_next_question_with_options( |
|
st.session_state.conversation, |
|
st.session_state.mental_health_scores |
|
) |
|
|
|
st.session_state.current_options = options |
|
st.session_state.user_submitted = False |
|
|
|
def handle_custom_submit(): |
|
if st.session_state.custom_input: |
|
|
|
st.session_state.conversation.append(st.session_state.custom_input) |
|
|
|
|
|
update_mental_health_scores(st.session_state.custom_input) |
|
|
|
|
|
st.session_state.other_selected = False |
|
|
|
|
|
st.session_state.user_submitted = True |
|
|
|
|
|
st.session_state.custom_input = "" |
|
|
|
|
|
with st.sidebar: |
|
st.header("Controls") |
|
|
|
|
|
st.subheader("AI Model") |
|
llm_option = st.radio( |
|
"Select AI Model", |
|
["LLaMA3-70B (Advanced)", "Blenderbot (Simple Conversation)"], |
|
index=0 if st.session_state.llm_service == "llama3" else 1 |
|
) |
|
|
|
|
|
if (llm_option == "LLaMA3-70B (Advanced)" and st.session_state.llm_service != "llama3") or \ |
|
(llm_option == "Blenderbot (Simple Conversation)" and st.session_state.llm_service != "blenderbot"): |
|
|
|
st.session_state.llm_service = "llama3" if llm_option == "LLaMA3-70B (Advanced)" else "blenderbot" |
|
|
|
|
|
st.session_state.conversation = [] |
|
st.session_state.therapy_state = "initial" |
|
st.session_state.mental_health_scores = { |
|
"anxiety": 0, |
|
"depression": 0, |
|
"stress": 0, |
|
"loneliness": 0, |
|
"grief": 0, |
|
"relationship_issues": 0, |
|
"self_esteem": 0, |
|
"trauma": 0 |
|
} |
|
st.session_state.assessment_progress = 0 |
|
st.session_state.current_question = None |
|
st.session_state.current_options = None |
|
st.session_state.user_submitted = False |
|
st.session_state.severity_rating = None |
|
st.session_state.sentiment_analysis = [] |
|
st.session_state.other_selected = False |
|
|
|
|
|
st.success(f"Switched to {llm_option}. Starting new conversation.") |
|
st.rerun() |
|
|
|
|
|
if st.session_state.mental_health_scores: |
|
st.subheader("Mental Health Indicators") |
|
for issue, score in sorted(st.session_state.mental_health_scores.items(), key=lambda x: x[1], reverse=True): |
|
|
|
if score > 0.5: |
|
|
|
display_name = issue.replace("_", " ").title() |
|
|
|
color_intensity = min(score / 15, 1.0) |
|
color = f"rgba(255, {int(255*(1-color_intensity))}, {int(255*(1-color_intensity))}, 0.8)" |
|
st.markdown( |
|
f"""<div style="background-color: {color}; padding: 5px; border-radius: 5px;"> |
|
{display_name}: {score:.1f}</div>""", |
|
unsafe_allow_html=True |
|
) |
|
|
|
|
|
st.subheader("Settings") |
|
delay_option = st.checkbox("Simulate therapist typing delay", value=st.session_state.response_delay) |
|
if delay_option != st.session_state.response_delay: |
|
st.session_state.response_delay = delay_option |
|
|
|
|
|
st.subheader("Session") |
|
if st.button("Start New Conversation"): |
|
st.session_state.conversation = [] |
|
st.session_state.therapy_state = "initial" |
|
st.session_state.mental_health_scores = { |
|
"anxiety": 0, |
|
"depression": 0, |
|
"stress": 0, |
|
"loneliness": 0, |
|
"grief": 0, |
|
"relationship_issues": 0, |
|
"self_esteem": 0, |
|
"trauma": 0 |
|
} |
|
st.session_state.assessment_progress = 0 |
|
st.session_state.current_question = None |
|
st.session_state.current_options = None |
|
st.session_state.user_submitted = False |
|
st.session_state.severity_rating = None |
|
st.session_state.sentiment_analysis = [] |
|
st.session_state.other_selected = False |
|
st.rerun() |
|
|
|
|
|
st.header("Therapeutic Conversation") |
|
|
|
|
|
st.caption(f"Using {'LLaMA3-70B' if st.session_state.llm_service == 'llama3' else 'Blenderbot'} for conversation") |
|
|
|
|
|
chat_container = st.container() |
|
|
|
|
|
with chat_container: |
|
if st.session_state.conversation: |
|
for i, message in enumerate(st.session_state.conversation): |
|
if i % 2 == 1: |
|
with st.chat_message("user"): |
|
st.write(message) |
|
else: |
|
with st.chat_message("assistant", avatar="🧠"): |
|
st.write(message) |
|
else: |
|
st.write("No conversation history yet.") |
|
|
|
|
|
if hasattr(st.session_state, 'therapy_state') and st.session_state.therapy_state == "ended": |
|
|
|
|
|
pass |
|
|
|
|
|
elif st.session_state.therapy_state == "initial": |
|
initial_greeting = "Hello, I'm here to provide a safe space for you to talk. How are you feeling today?" |
|
|
|
with chat_container: |
|
with st.chat_message("assistant", avatar="🧠"): |
|
st.write(initial_greeting) |
|
|
|
|
|
with st.form(key="initial_response_form"): |
|
st.text_area("Share how you're feeling:", key="initial_response", height=100) |
|
st.form_submit_button("Send", on_click=submit_initial_response) |
|
|
|
|
|
elif st.session_state.therapy_state == "therapy": |
|
|
|
if assessment_complete(st.session_state.mental_health_scores, len(st.session_state.conversation)): |
|
with st.spinner("Preparing assessment..."): |
|
assessment, severity = generate_assessment_summary( |
|
st.session_state.conversation, |
|
st.session_state.mental_health_scores |
|
) |
|
|
|
|
|
resources = generate_resources(st.session_state.mental_health_scores) |
|
|
|
|
|
st.session_state.assessment = assessment |
|
st.session_state.resources = resources |
|
st.session_state.severity_rating = severity |
|
st.session_state.therapy_state = "summary" |
|
|
|
|
|
transition_message = "I've had a chance to reflect on our conversation. Would you like to see a summary of what I'm hearing from you, along with some resources that might be helpful?" |
|
st.session_state.conversation.append(transition_message) |
|
|
|
|
|
st.rerun() |
|
|
|
|
|
if st.session_state.user_submitted: |
|
|
|
last_user_message = st.session_state.conversation[-1] |
|
|
|
with st.spinner("Thinking..."): |
|
|
|
if st.session_state.response_delay: |
|
time.sleep(1.5) |
|
|
|
|
|
response = generate_therapeutic_response( |
|
last_user_message, |
|
st.session_state.conversation, |
|
st.session_state.mental_health_scores |
|
) |
|
|
|
|
|
st.session_state.conversation.append(response) |
|
|
|
|
|
question, options = generate_next_question_with_options( |
|
st.session_state.conversation, |
|
st.session_state.mental_health_scores |
|
) |
|
|
|
st.session_state.current_options = options |
|
|
|
|
|
st.session_state.user_submitted = False |
|
|
|
|
|
st.rerun() |
|
|
|
|
|
if not st.session_state.user_submitted and not st.session_state.other_selected: |
|
|
|
if st.session_state.current_options: |
|
options_container = st.container() |
|
with options_container: |
|
st.radio( |
|
"Quick responses:", |
|
st.session_state.current_options, |
|
key="selected_option" |
|
) |
|
|
|
cols = st.columns([1, 1]) |
|
with cols[0]: |
|
if st.button("Send Quick Response"): |
|
if "selected_option" in st.session_state and st.session_state.selected_option: |
|
if st.session_state.selected_option == "Other": |
|
st.session_state.other_selected = True |
|
else: |
|
|
|
st.session_state.conversation.append(st.session_state.selected_option) |
|
|
|
|
|
update_mental_health_scores(st.session_state.selected_option) |
|
|
|
st.session_state.user_submitted = True |
|
st.rerun() |
|
|
|
with cols[1]: |
|
if st.button("I'd prefer to type my response"): |
|
st.session_state.other_selected = True |
|
st.rerun() |
|
|
|
|
|
if st.session_state.other_selected: |
|
with st.form(key="custom_response_form"): |
|
st.text_area("Your response:", key="custom_input", height=100) |
|
st.form_submit_button("Send", on_click=handle_custom_submit) |
|
|
|
|
|
elif st.session_state.therapy_state == "summary": |
|
|
|
def submit_summary_choice(): |
|
if st.session_state.summary_choice: |
|
|
|
st.session_state.conversation.append(st.session_state.summary_choice) |
|
|
|
|
|
if "yes" in st.session_state.summary_choice.lower(): |
|
|
|
st.session_state.show_interactive_summary = True |
|
else: |
|
|
|
st.session_state.conversation.append("That's completely fine. We can continue our conversation. What would you like to talk about next?") |
|
st.session_state.therapy_state = "therapy" |
|
|
|
|
|
if len(st.session_state.conversation) % 2 == 1: |
|
with st.form(key="summary_choice_form"): |
|
st.radio( |
|
"Would you like to see a summary and helpful resources?", |
|
["Yes, I'd like to see the summary", "No, I'd prefer to continue talking"], |
|
key="summary_choice" |
|
) |
|
st.form_submit_button("Send", on_click=submit_summary_choice) |
|
|
|
|
|
elif len(st.session_state.conversation) % 2 == 0 and len(st.session_state.conversation) >= 2: |
|
|
|
if hasattr(st.session_state, 'show_interactive_summary') and st.session_state.show_interactive_summary: |
|
|
|
|
|
next_action = display_interactive_summary( |
|
st.session_state.mental_health_scores, |
|
st.session_state.assessment, |
|
st.session_state.resources |
|
) |
|
|
|
|
|
if next_action == "continue": |
|
|
|
st.session_state.therapy_state = "therapy" |
|
st.session_state.conversation.append("Let's continue our conversation. What's on your mind?") |
|
st.session_state.show_interactive_summary = False |
|
elif next_action == "new": |
|
|
|
st.session_state.conversation = [] |
|
st.session_state.therapy_state = "initial" |
|
st.session_state.mental_health_scores = { |
|
"anxiety": 0, |
|
"depression": 0, |
|
"stress": 0, |
|
"loneliness": 0, |
|
"grief": 0, |
|
"relationship_issues": 0, |
|
"self_esteem": 0, |
|
"trauma": 0 |
|
} |
|
st.session_state.assessment_progress = 0 |
|
st.session_state.current_question = None |
|
st.session_state.current_options = None |
|
st.session_state.user_submitted = False |
|
st.session_state.severity_rating = None |
|
st.session_state.sentiment_analysis = [] |
|
st.session_state.other_selected = False |
|
st.session_state.show_interactive_summary = False |
|
elif next_action == "end": |
|
|
|
st.session_state.conversation.append("Thank you for talking with me today. Remember that this is just a simulation for educational purposes. If you're experiencing mental health challenges, please consider reaching out to a professional. Take care of yourself.") |
|
st.session_state.therapy_state = "ended" |
|
st.session_state.show_interactive_summary = False |
|
st.rerun() |
|
else: |
|
|
|
|
|
|
|
|
|
|
|
if hasattr(st.session_state, 'show_interactive_summary') and not st.session_state.show_interactive_summary and not any(st.session_state.assessment in msg for msg in st.session_state.conversation): |
|
st.session_state.conversation.append(st.session_state.assessment + "\n\n" + st.session_state.resources) |
|
|
|
|
|
final_options = [ |
|
"I'd like to continue our conversation", |
|
"I found this helpful, thank you", |
|
"I'd like to start a new conversation", |
|
"I'd like to learn more about specific resources", |
|
"Show me an interactive summary" |
|
] |
|
|
|
def handle_final_choice(): |
|
if st.session_state.final_choice: |
|
|
|
st.session_state.conversation.append(st.session_state.final_choice) |
|
|
|
if "continue" in st.session_state.final_choice.lower(): |
|
|
|
st.session_state.therapy_state = "therapy" |
|
st.session_state.conversation.append("I'm here to continue our conversation. What's on your mind?") |
|
elif "new" in st.session_state.final_choice.lower(): |
|
|
|
st.session_state.conversation = [] |
|
st.session_state.therapy_state = "initial" |
|
st.session_state.mental_health_scores = { |
|
"anxiety": 0, |
|
"depression": 0, |
|
"stress": 0, |
|
"loneliness": 0, |
|
"grief": 0, |
|
"relationship_issues": 0, |
|
"self_esteem": 0, |
|
"trauma": 0 |
|
} |
|
st.session_state.assessment_progress = 0 |
|
st.session_state.current_question = None |
|
st.session_state.current_options = None |
|
st.session_state.user_submitted = False |
|
st.session_state.severity_rating = None |
|
st.session_state.sentiment_analysis = [] |
|
st.session_state.other_selected = False |
|
st.rerun() |
|
|
|
elif "resources" in st.session_state.final_choice.lower(): |
|
|
|
with st.spinner("Finding more specific resources..."): |
|
detailed_resources = use_llama3_api( |
|
"Provide a detailed list of mental health resources including specific apps, websites, hotlines, and books. Include resources for both immediate crisis and long-term support.", |
|
max_tokens=600 |
|
) |
|
st.session_state.conversation.append("Here are some more detailed resources that might be helpful:\n\n" + detailed_resources) |
|
elif "interactive summary" in st.session_state.final_choice.lower(): |
|
|
|
st.session_state.show_interactive_summary = True |
|
elif 'end' in st.session_state.final_choice.lower() or "thank" in st.session_state.final_choice.lower(): |
|
|
|
st.session_state.conversation.append("Thank you for talking with me today. Remember that this is just a simulation for educational purposes. If you're experiencing mental health challenges, please consider reaching out to a professional. Take care of yourself.") |
|
st.session_state.therapy_state = "ended" |
|
st.rerun() |
|
|
|
with st.form(key="final_choice_form"): |
|
st.radio( |
|
"What would you like to do next?", |
|
final_options, |
|
key="final_choice" |
|
) |
|
st.form_submit_button("Send", on_click=handle_final_choice) |
|
|
|
|
|
if st.form_submit_button("End Session"): |
|
|
|
st.session_state.conversation.append("Thank you for talking with me today. Remember that this is just a simulation for educational purposes. If you're experiencing mental health challenges, please consider reaching out to a professional. Take care of yourself.") |
|
st.session_state.therapy_state = "ended" |
|
st.rerun() |
|
|
|
|
|
st.markdown("---") |
|
st.caption("**IMPORTANT DISCLAIMER:** This is an educational prototype only and should not be used for actual mental health support. The AI models used have limitations and may not provide accurate or appropriate responses. If you're experiencing mental health issues, please contact a qualified healthcare professional or a crisis service such as the National Suicide Prevention Lifeline at 988 or 1-800-273-8255.") |
|
|
|
|
|
if st.button("Back to Main Menu"): |
|
st.session_state.page = "main" |
|
st.rerun() |
|
|
|
|
|
if __name__ == "__main__": |
|
run_mental_health() |