temporarylogin540/safespace-ai-therapist
SafeSpace – AI Mental Health Therapist
SafeSpace is a tool-using AI agent for mental-health conversations. It doesn't just chat: it decides when to act.
- 💬 Talks with empathetic, therapist-style guidance
- 📍 Finds real therapists near a location (Google Maps)
- 🚨 Places an emergency phone call when someone is in crisis (Twilio Voice)
- 📱 Works in a web chat (Streamlit, streamed word by word) and on WhatsApp (Twilio)
Live demo: https://huggingface.co/spaces/temporarylogin540/safespace-ai-therapist
⚠️ Educational project, not a substitute for professional care or emergency services. If you are in danger, contact your local emergency number.
How it works
Streamlit chat ──POST /ask_stream────┐
├──► FastAPI ──► LangGraph ReAct agent (Groq · gpt-oss-120b)
WhatsApp ──Twilio──POST /whatsapp_ask┘ │ picks a tool
├─► ask_mental_health_specialist (therapist-persona LLM)
├─► find_nearby_therapists_by_location (Google Maps)
└─► emergency_call_tool (Twilio voice call)Run it locally
1. Install (needs Python 3.11+ and uv)
git clone https://github.com/jindal-rohit540/ai-therapist.git
cd ai-therapist
uv sync2. Add your keys
cp .env.example .env # then fill it inOnly the Groq key is required. Without the others, those tools reply that they aren't configured.
3. Start the backend and the frontend (two terminals)
uv run uvicorn main:app --app-dir backend --port 8000 --reload
uv run streamlit run frontend.pyOpen http://localhost:8501. The API docs are at http://localhost:8000/docs.
API
curl -X POST localhost:8000/ask -H "Content-Type: application/json" \
-d '{"message": "I have been feeling anxious lately."}'
curl -N -X POST localhost:8000/ask_stream -H "Content-Type: application/json" \
-d '{"message": "I have been feeling anxious lately."}' # -N: watch tokens arrive
curl -X POST localhost:8000/whatsapp_ask -d "Body=Hello" # simulate TwilioHow streaming works: the agent runs with graph.stream(inputs, stream_mode=["updates", "messages"]). "updates" reports which tool ran and "messages" delivers the LLM's tokens. Only tokens from the agent node are forwarded, so the specialist LLM running inside a tool doesn't leak into the reply. WhatsApp can't stream: Twilio expects the full reply in one response.
WhatsApp (Twilio sandbox)
- Open the sandbox at https://console.twilio.com/us1/develop/sms/try-it-out/whatsapp-learn. It shows the sandbox number and your
join <code>. - From WhatsApp, send
join <code>to the sandbox number. - In Sandbox settings, set When a message comes in to your public URL +
/whatsapp_ask(methodPOST): - Deployed on Hugging Face:
https://<username>-<space-name>.hf.space/whatsapp_ask - Running locally: expose port 8000 with a tunnel such as ngrok (
ngrok http 8000) - Chat. Long replies arrive as several messages, because WhatsApp caps one message at 1600 characters.
If nothing comes back, check Twilio's error log. Error 11200 means Twilio couldn't reach your URL.
Deploy to Hugging Face Spaces
A Space exposes one public port (7860), so the container runs nginx in front of both servers (see start.sh):
┌─ /ask, /ask_stream, /whatsapp_ask, /docs ──► FastAPI (127.0.0.1:8000)
internet ──► nginx:7860┤
└─ everything else ─────────────────────────► Streamlit (127.0.0.1:8501)- Create a Space at https://huggingface.co/new-space → Docker → Blank. Keep it Public, because Twilio can't reach a private Space.
- Push this repo to it. Leave out
.envand.venv/. - In Settings → Variables and secrets, add every key from
.env.exampleas a secret. - The build takes about 3–5 minutes. The app is then served at
https://<username>-<space-name>.hf.space.
Free Spaces sleep after 48 hours without traffic, so open the page once before a demo.
