Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
cb1e9fb
first commit
gituser14d Jul 25, 2025
b891fa0
Collaborative Confidence Model summary submission
gituser14d Jul 25, 2025
ec821d6
Add files via upload
gituser14d Jul 25, 2025
eeead28
Delete Downloads directory
gituser14d Jul 25, 2025
5039c01
Delete Collaborative Confidence Model summary.rtf
gituser14d Jul 25, 2025
2cfb067
Add files via upload
gituser14d Jul 25, 2025
c357384
Add files via upload
gituser14d Jul 25, 2025
770de09
Add files via upload
hxryy7 Jul 26, 2025
ec5fe0f
Add files via upload
Gargi2023 Jul 27, 2025
afbbe8f
Add Mood Prediction Model Explanation
MeharX10 Jul 30, 2025
d310384
Add files via upload
gituser14d Aug 2, 2025
c2fb3f5
Add files via upload
gituser14d Aug 3, 2025
d25a85e
Add files via upload
hxryy7 Aug 11, 2025
a8c5cd6
Add files via upload (MoodPredictionModel.ipynb)
MeharX10 Aug 11, 2025
f08e885
Add files via upload (Dashboard_Calculations.ipynb, mental_health_tre…
MeharX10 Aug 11, 2025
84852e5
Add files via upload
gituser14d Aug 27, 2025
7d67a3c
Add files via upload
gituser14d Aug 30, 2025
796a889
Add files via upload
gituser14d Sep 7, 2025
6c6f45e
Add Chatbot: Conversation Script & Security Measures
MeharX10 Sep 22, 2025
38bc01c
Add Design_Visuals: Branding & Storytelling wireframe deliverables
MeharX10 Sep 22, 2025
d4ad03b
Add files via upload
gituser14d Sep 22, 2025
c58f715
the chatroom codes
Gargi2023 Sep 27, 2025
776f542
Add 'projects/mental_health_hub/' from commit 'c58f715d2f7182d4bb820a…
MeharX10 Sep 28, 2025
3a57583
chore: ignore caches and OS files
MeharX10 Sep 28, 2025
6b2343d
chore(mhhub): flatten notebooks/design one level for simpler navigation
MeharX10 Sep 28, 2025
7575c4c
docs(mhhub): add minimal project README aligned with monorepo style
MeharX10 Sep 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ Desktop.ini

# Linux files
*~
__pycache__/
*.pyc
.ipynb_checkpoints/
.DS_Store
31 changes: 31 additions & 0 deletions projects/mental_health_hub/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Mental Health Hub

Team project integrated into the Redback Senior (Wearables for Seniors) monorepo.

## Location
`projects/mental_health_hub/`

## Structure
- `apps/`
- `chatbot/` – conversation script and security demos
- `chatroom/` – simple client/server demo
- `dashboard/mental_health_dashboard/` – dashboard app (components, utils, data)
- `streamlit_hub/` – streamlit modules and entry script
- `notebooks/`
- `dashboard_calculations/` – notebook + generated plots + CSV
- `mood_prediction_model/` – notebook + figures
- `design/` – branding assets and wireframes
- `docs/` – PDF/RTF deliverables (guidelines, plans, threat model, etc.)
- `scripts/` – utility scripts
- `security/` – auth and security code
- `tests/` – test files

## Notes
- Imported with full Git history from the original team repo.
- Files reorganized into the structure above (history preserved via `git mv`).

## Contributors
- MeharX10 (Bhanu Pratap Singh Mehar)
- gituser14d (James Nardella)
- hxryy7 (Harvardaan Singh Chahal)
- Gargi2023 (Gargi Sarma)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
#!/usr/bin/env python3
"""
chatbot_conversation_script.py
(Branching Logic + Sample Output)
- Provides a simple, deterministic wellness chatbot with branching logic.
- Covers mood-aware suggestions, check-ins, and escalation (crisis safety).
- Includes both a JSON "logic tree" and Python if/elif rules.

Run:
$ python chatbot_conversation_script.py --demo # prints 4 demo conversations
$ python chatbot_conversation_script.py --mood 55 --say "tips for sleep"
$ python chatbot_conversation_script.py --interactive # (optional) try a quick CLI chat
"""

from __future__ import annotations
import argparse
import json
import re
from dataclasses import dataclass, field
from typing import Dict, List, Tuple

# ---------- Utility: lightweight input sanitizer ----------
def sanitize(text: str) -> str:
text = (text or "").lower().strip()
text = re.sub(r"\s+", " ", text)
# Remove any control characters
text = "".join(ch for ch in text if ch.isprintable())
return text


# ---------- Data: a JSON-like branching tree (also saved to logic_tree.json alongside this script) ----------
LOGIC_TREE: Dict = {
"buckets": {
"very_low": {"range": [0, 25], "tone": "urgent_gentle"},
"low": {"range": [26, 49], "tone": "gentle"},
"moderate": {"range": [50, 74], "tone": "supportive"},
"high": {"range": [75, 100], "tone": "celebratory"},
},
"intents": {
"sleep": [
"Try a consistent bedtime/wake-up window. Keep screens away for 60 minutes before sleep.",
"A short wind-down ritual (dim lights, gentle music, 5-minute breath focus) helps the brain switch off.",
"If you wake at night, avoid clock-watching—read something light under warm light for 10–15 minutes."
],
"stress": [
"Box breathing: inhale 4s, hold 4s, exhale 4s, hold 4s—repeat for 2 minutes.",
"Write down the top 1–2 worries, circle what you can control, and pick one small action today.",
"Take a 10-minute walk outdoors to reset your nervous system."
],
"lonely": [
"Call or text a trusted person and share one highlight from your day.",
"Consider local community groups or a short volunteer session this week.",
"Schedule a brief chat with family/friends after dinner—put it on the calendar."
],
"activity": [
"Try a 5–10 minute gentle stretch after meals.",
"If safe, add a 15-minute easy walk today—track how you feel afterwards.",
"Balance: 3 days of light walking + 2 days of flexibility in a week works well."
],
"hydration": [
"Keep water visible; aim for small sips each hour.",
"Pair water with regular routines (after brushing teeth, after each phone call).",
"Try herbal tea in the evening to reduce caffeine."
],
"general": [
"Small steps count—pick one action you can do in under 5 minutes.",
"Sunlight in the morning and gentle movement improve mood and sleep.",
"Keep meals regular and simple; stable energy helps stable mood."
]
},
"escalation": {
"immediate_keywords": [
"suicide","kill myself","hurt myself","self harm","end my life","harm myself"
],
"thresholds": {
"offer_support_at_or_below": 39,
"urgent_at_or_below": 25
},
"messages": {
"urgent": (
"I'm really glad you reached out. You deserve immediate support. "
"If you're in Australia and in danger, please call 000 now. You can also contact "
"Lifeline 13 11 14 or Beyond Blue 1300 22 4636. If outside Australia, please use your local emergency number."
),
"offer": (
"It sounds like a tough time. Would you like me to share support options? "
"In Australia: Lifeline 13 11 14, Beyond Blue 1300 22 4636. If outside AU, contact local services."
)
}
}
}


def save_logic_tree(path: str = "logic_tree.json") -> None:
with open(path, "w", encoding="utf-8") as f:
json.dump(LOGIC_TREE, f, indent=2, ensure_ascii=False)


# ---------- Core Chatbot ----------
CRISIS_REGEX = re.compile("|".join(map(re.escape, LOGIC_TREE["escalation"]["immediate_keywords"])), re.I)


@dataclass
class WellnessChatbot:
tree: Dict = field(default_factory=lambda: LOGIC_TREE)

def bucket_for(self, mood_score: int) -> str:
"""Pick a mood bucket based on score 0..100."""
ms = max(0, min(100, int(mood_score)))
for name, info in self.tree["buckets"].items():
lo, hi = info["range"]
if lo <= ms <= hi:
return name
return "moderate" # safe default

def maybe_escalate(self, user: str, mood_score: int) -> Tuple[bool, str]:
"""
Crisis-aware check.
- Immediate escalation if crisis keywords present or mood <= urgent threshold.
- Offer support if mood <= offer threshold.
"""
ms = max(0, min(100, int(mood_score)))
if CRISIS_REGEX.search(user) or ms <= self.tree["escalation"]["thresholds"]["urgent_at_or_below"]:
return True, self.tree["escalation"]["messages"]["urgent"]
if ms <= self.tree["escalation"]["thresholds"]["offer_support_at_or_below"]:
return True, self.tree["escalation"]["messages"]["offer"]
return False, ""

def intent_of(self, user: str) -> str:
"""
Simple keyword-based intent detection for a deterministic demo.
Covers common wellness themes.
"""
user = sanitize(user)
if any(k in user for k in ("sleep", "insomnia", "tired", "rest")):
return "sleep"
if any(k in user for k in ("stress", "stressed", "overwhelmed", "anxious", "anxiety")):
return "stress"
if any(k in user for k in ("lonely", "alone", "isolate")):
return "lonely"
if any(k in user for k in ("walk", "exercise", "move", "activity", "workout", "gym")):
return "activity"
if any(k in user for k in ("water", "hydration", "hydrate", "drink")):
return "hydration"
return "general"

def tone_prefix(self, bucket: str) -> str:
tone = self.tree["buckets"][bucket]["tone"]
return {
"urgent_gentle": "I'm here with you. ",
"gentle": "I hear you. ",
"supportive": "Got it. ",
"celebratory": "Love that! "
}.get(tone, "")

def suggest(self, intent: str) -> str:
tips = self.tree["intents"].get(intent) or self.tree["intents"]["general"]
# Rotate suggestions deterministically by intent: choose index via hash modulo list length
idx = abs(hash(intent)) % len(tips)
return tips[idx]

def respond(self, user: str, mood_score: int) -> str:
# Crisis / escalation check
escalate, msg = self.maybe_escalate(user, mood_score)
if escalate:
return msg

bucket = self.bucket_for(mood_score)
prefix = self.tone_prefix(bucket)
intent = self.intent_of(user)
tip = self.suggest(intent)

# A small, mood-aware suffix to promote next-step actions.
next_step = {
"very_low": "If helpful, we can try one tiny step together now.",
"low": "One small step today can help—I'm happy to suggest one.",
"moderate": "Pick one small action you can do in under 5 minutes.",
"high": "Keep doing what works—consistency compounds!",
}[bucket]

return f"{prefix}{tip} {next_step}"

def check_in_prompt(self, mood_score: int) -> str:
"""A friendly check-in line based on mood bucket."""
bucket = self.bucket_for(mood_score)
prompts = {
"very_low": "How are you holding up today? Even a few words can help me support you.",
"low": "Thanks for checking in. What's one thing on your mind right now?",
"moderate": "How are you feeling today—okay, a bit stressed, or fairly steady?",
"high": "Great to see you! Want a quick tip or to celebrate a win?"
}
return prompts[bucket]


# ---------- Demo scenarios ----------
def demo_runs() -> List[Tuple[str, List[Tuple[str, str]]]]:
bot = WellnessChatbot()
scenarios = []

# Scenario 1: Very low mood (escalation - urgent)
ms = 20
s1 = [
("[System]", f"Check-in: {bot.check_in_prompt(ms)}"),
("User", "I feel hopeless and might hurt myself."),
("Bot", bot.respond("I feel hopeless and might hurt myself.", ms)),
]
scenarios.append(("Scenario 1 – Very low (urgent escalation)", s1))

# Scenario 2: Low mood (offer support)
ms = 35
s2 = [
("[System]", f"Check-in: {bot.check_in_prompt(ms)}"),
("User", "I'm stressed and sleeping badly."),
("Bot", bot.respond("I'm stressed and sleeping badly.", ms)),
]
scenarios.append(("Scenario 2 – Low (offer support)", s2))

# Scenario 3: Moderate mood (actionable tip)
ms = 60
s3 = [
("[System]", f"Check-in: {bot.check_in_prompt(ms)}"),
("User", "Any tips for better sleep?"),
("Bot", bot.respond("Any tips for better sleep?", ms)),
]
scenarios.append(("Scenario 3 – Moderate (sleep tip)", s3))

# Scenario 4: High mood (celebratory reinforcement)
ms = 90
s4 = [
("[System]", f"Check-in: {bot.check_in_prompt(ms)}"),
("User", "Feeling great! What should I focus on this week?"),
("Bot", bot.respond("Feeling great! What should I focus on this week?", ms)),
]
scenarios.append(("Scenario 4 – High (celebrate & maintain)", s4))

return scenarios


def print_scenarios(scenarios: List[Tuple[str, List[Tuple[str, str]]]]) -> str:
import textwrap
lines: List[str] = []
for title, turns in scenarios:
lines.append("=" * len(title))
lines.append(title)
lines.append("=" * len(title))
for speaker, text in turns:
wrapped = textwrap.fill(text, width=100)
lines.append(f"{speaker}: {wrapped}")
lines.append("")
output = "\n".join(lines)
print(output)
return output


# ---------- CLI ----------
def main():
parser = argparse.ArgumentParser(description="Deterministic Wellness Chatbot (branching logic)")
parser.add_argument("--demo", action="store_true", help="Run 4 demo conversations (prints expected output).")
parser.add_argument("--mood", type=int, default=60, help="Mood score 0..100 (default 60)")
parser.add_argument("--say", type=str, default="", help="What the user says (single turn)")
parser.add_argument("--interactive", action="store_true", help="Simple interactive CLI chat (3 turns)")
args = parser.parse_args()

# Always save the JSON logic tree alongside this script (meets 'JSON or Python' requirement).
save_logic_tree("logic_tree.json")

bot = WellnessChatbot()

if args.demo:
out = print_scenarios(demo_runs())
# Also store to a transcript file for evidence
with open("sample_transcripts.txt", "w", encoding="utf-8") as f:
f.write(out)
return

if args.interactive:
ms = args.mood
print(f"🤖 Wellness Assistant (mood_score={ms})")
print(f"Check-in: {bot.check_in_prompt(ms)}")
for i in range(3):
try:
user = input("You: ").strip()
except EOFError:
break
reply = bot.respond(user, ms)
print(f"Bot: {reply}")
return

# Single turn
say = args.say.strip() or "Any tips to reduce stress?"
reply = bot.respond(say, args.mood)
print(f"[Mood {args.mood}] You: {say}")
print(f"[Mood {args.mood}] Bot: {reply}")


if __name__ == "__main__":
main()
Loading
Loading