An AI-powered therapy application that provides emotional support, therapeutic tools, and builds a persistent memory of the user over time.
URL: https://ai-therapist-d691c.web.app
- Gemini 2.5 Flash integration for natural, empathetic conversations
- Therapist Persona - Customizable AI therapist with a warm, supportive personality
- Context-Aware Responses - Remembers previous sessions and adapts responses
- Intelligent Activity Detection - Auto-triggers breathing exercises or emotion check-ins based on conversation
- Learning Questions - AI asks follow-up questions to learn about the user (40% probability after first message)
- Learns About You - Extracts personal facts, emotions, topics, and preferences from every message
- Memory Categories:
- Personal - Name, location, job, family, hobbies, age, pets
- Emotions - Anxiety, sadness, anger, happiness, fatigue, confusion, shame
- Topics - Problems, goals, relationships, work issues
- Preferences - Communication style, boundaries, coping strategies
- Contextual Retrieval - AI finds and references relevant memories when you discuss related topics
- Memory Importance Scores - Each memory rated 1-10 for relevance
- Memory Deduplication - Prevents storing duplicate memories (>80% similarity check)
- 100 Memory Cap - Automatically removes lowest importance memories when limit reached
- Memory Indicators - Sparkle icon shows when memory is saved from your message
- Active Learning - 25+ learning questions to gather information about the user
- Memory Viewer - View all stored memories in Settings
- Search Memories - Search through your memories
- Filter by Category - Filter memories by personal, topic, emotion, or preference
- Delete Memories - Remove individual memories
- Memory Statistics - Shows category counts and average importance
- Memory Age Display - Shows when each memory was saved (e.g., "2h ago", "3d ago")
- Box Breathing Exercise - 4-4-4-4 guided breathing technique with visual circle animation
- Emotion Check-In - Track feelings across 4 dimensions (Anxiety, Mood, Stress, Energy) using 1-10 sliders
- Sound Therapy - Ambient nature sounds (rain, ocean, forest, fire, wind) for relaxation
- Journal - Private journal entries with create, edit, and delete functionality
- Emotion History - Store all emotion check-ins in database
- Mood Charts - Visual line chart showing emotion trends over time (7/30/90 days)
- Average Scores - Display average for each emotion dimension
- Trend Indicators - Shows if emotions are trending up/down/stable
- Voice Input - Speech-to-text using Web Speech API
- Voice Output - Text-to-speech using browser's Speech Synthesis
- Multiple Voice Selection - Choose from 9+ voices (Moira, Daniel, Karen, Samantha, etc.) in Settings
- TTS Toggle - Enable/disable voice output in Settings
- TTS Prompt - Friendly prompt to enable voice after first conversation
- Session Management - Automatic daily sessions with session history
- Real-time Typing Indicators - Shows when AI is responding
- Message Bubbles - Clean UI for user and bot messages
- Session Sidebar - View and switch between past sessions on mobile
- Auto-Scroll - Automatically scrolls to new messages
- Firebase Auth - Email/password and Google sign-in
- Supabase Backend - PostgreSQL database for cloud persistence
- Local Storage - Fast local caching of sessions for offline use
- Cloud Sync - Supabase for cross-device synchronization
- Responsive Design - Works on mobile and desktop
- Mobile Optimizations - Touch-friendly 44px targets, safe area padding, proper viewport handling
- Onboarding Flow - 3-step setup (Sign in β Name therapist β Voice selection)
- Settings Dialog - Customize therapist name, voice, TTS toggle, view memories, mood history
- Error Boundary - Graceful error handling with user-friendly messages
- Landing Page - Beautiful landing page before sign-in
| Layer | Technology |
|---|---|
| Frontend | React 18 + TypeScript |
| Styling | Tailwind CSS + Shadcn UI |
| Build Tool | Vite |
| AI | Google Gemini 2.5 Flash |
| Database | Supabase (PostgreSQL) |
| Auth | Firebase Auth |
| Hosting | Firebase Hosting |
| Voice | Web Speech API (Speech Recognition + Speech Synthesis) |
| Charts | Recharts |
CREATE TABLE sessions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
date TEXT NOT NULL,
timestamp BIGINT NOT NULL
);CREATE TABLE messages (
id TEXT PRIMARY KEY,
session_id TEXT REFERENCES sessions(id),
role TEXT NOT NULL CHECK (role IN ('user', 'bot')),
content TEXT NOT NULL,
timestamp BIGINT NOT NULL
);CREATE TABLE memories (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL,
content TEXT NOT NULL,
category TEXT NOT NULL CHECK (category IN ('personal', 'topic', 'emotion', 'preference')),
importance INTEGER NOT NULL DEFAULT 5 CHECK (importance >= 1 AND importance <= 10),
source_message_id TEXT,
created_at BIGINT NOT NULL,
last_referenced_at BIGINT,
is_active BOOLEAN NOT NULL DEFAULT true
);CREATE TABLE emotion_checkins (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
session_id TEXT,
timestamp BIGINT NOT NULL,
anxiety INTEGER,
mood INTEGER,
stress INTEGER,
energy INTEGER
);CREATE TABLE journal_entries (
id TEXT PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL,
title TEXT,
content TEXT NOT NULL,
created_at BIGINT NOT NULL,
updated_at BIGINT
);βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Message β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Memory Extractor β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Personal β β Emotions β β Topics β β
β β Facts β β Detection β β Extraction β β
β β - Name β β - Anxiety β β - Problems β β
β β - Location β β - Sadness β β - Goals β β
β β - Job β β - Anger β β - Work β β
β β - Family β β - Happiness β β - Relations β β
β β - Hobbies β β - Fatigue β β β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β ββββββββββββββββ β
β β Preferences β β
β β - Boundaries β β
β β - Coping β β
β β - Style β β
β ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Deduplication Check β
β - Compare with existing memories β
β - Skip if duplicate (>80% similarity) β
β - Enforce 100 memory cap β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Save to Supabase β
β - Insert into memories table β
β - Set importance score (1-10) β
β - Mark category (personal/topic/emotion/preference) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Chat Flow β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββββΌββββββββββββββββββββββ
βΌ βΌ βΌ
βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
β Send Message β β Extract β β AI Response β
β to Gemini β β Memories β β with Context β
βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββ
β Check Learning Opportunity β
β - 40% probability β
β - After 1+ messages β
β - Select unasked question β
βββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββ
β Ask Follow-up Question β
β - "I'd love to know..." β
β - Reference past emotions β
βββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Voice Input β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Web Speech Recognition β
β - Continuous = false β
β - Interim results = true β
β - Language: en-US β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Transcript Handling β
β - Real-time interim display β
β - Final transcript on speech end β
β - Send to chat β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Voice Output β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Web Speech Synthesis β
β - Queue-based playback β
β - Preferred voices: Karen, Samantha, Daniel, Moira, etc. β
β - Rate: 1.0, Pitch: 1.0, Volume: 1.0 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Hook | Purpose |
|---|---|
useChat |
Manages chat state, Gemini integration, memory extraction |
useMemory |
Memory CRUD operations with deduplication |
useAuth |
Firebase authentication state |
useSettings |
User preferences (TTS, voice selection) |
useTextToSpeech |
Text-to-speech with voice queue |
useSpeechRecognition |
Speech-to-text with interim results |
| Service | Purpose |
|---|---|
memoryExtractor.ts |
Regex-based extraction of personal facts, emotions, topics, preferences |
learningQuestions.ts |
Generates learning questions, follow-ups, and contextual memory retrieval |
db.ts |
Supabase database operations for sessions, messages, memories, emotions, journal |
gemini.ts |
Gemini AI configuration |
| Component | Purpose |
|---|---|
ChatApp.tsx |
Main chat interface with session management |
MessageBubble.tsx |
Individual chat messages with memory indicator |
MessagesList.tsx |
Scrollable message container |
InputArea.tsx |
Text input, voice recorder, activities menu |
MemoryViewer.tsx |
View/search/filter/delete memories with stats |
MoodChart.tsx |
Recharts visualization of emotion history |
Journal.tsx |
Journal entry create/edit/delete UI |
EmotionScaleSliders.tsx |
1-10 emotion tracking with presets |
BreathingExercise.tsx |
Box breathing UI with animation |
SoundTherapy.tsx |
Ambient sound player |
VoiceRecorder.tsx |
Speech input UI |
SettingsDialog.tsx |
User preferences with tabs |
Sidebar.tsx |
Session list navigation |
AppLayout.tsx |
Responsive layout with mobile sidebar |
Onboarding.tsx |
3-step initial setup |
LandingPage.tsx |
Pre-auth landing page |
VITE_GEMINI_API_KEY=your_gemini_api_key
VITE_SUPABASE_URL=your_supabase_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
VITE_FIREBASE_API_KEY=your_firebase_api_key
VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
VITE_FIREBASE_APP_ID=your_app_id
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id- Node.js 18+
- npm or yarn
- Google account (for Gemini API)
- Supabase account (free tier works)
- Firebase account (free tier works)
git clone https://github.com/grahamrr7/ai_therapist.git
cd ai_therapist
npm install- Go to https://supabase.com and create a new project
- In the SQL Editor, run all migrations in
supabase/migrations/ - Go to Project Settings β API
- Copy the Project URL and anon public key
- Go to https://console.firebase.google.com and create a project
- Enable Authentication: Enable Email/Password and Google sign-in
- Go to Project Settings β General
- Copy your Web app config (apiKey, authDomain, projectId, etc.)
- Go to https://aistudio.google.com/app/apikey
- Create a new API key
- Copy the key
Create a .env file in the project root:
VITE_GEMINI_API_KEY=your_gemini_key
VITE_SUPABASE_URL=your_supabase_url
VITE_SUPABASE_ANON_KEY=your_supabase_anon_key
VITE_FIREBASE_API_KEY=your_firebase_api_key
VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
VITE_FIREBASE_APP_ID=your_app_id
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id# Development
npm run dev
# Production build
npm run build
# Deploy to Firebase
npx firebase deploy- Names: "my name is X", "I'm X", "call me X"
- Locations: "I live in X", "I'm from X", "based in X"
- Occupation: "I work as X", "my job is X", "I do X for a living"
- Family: "my husband/wife/partner", "I have kids", "my mom/dad"
- Hobbies: "in my free time I X", "I enjoy X", "my hobby is X"
- Pets: "I have a dog/cat", "my pet is..."
- Anxiety: anxious, worried, nervous, panic, overwhelmed, stressed, fear, scared
- Sadness: sad, depressed, down, hopeless, heartbroken, lonely, empty
- Anger: angry, frustrated, annoyed, irritated, furious, mad
- Happiness: happy, joy, excited, grateful, blessed, content, peaceful
- Fatigue: tired, exhausted, drained, burnout, drowsy, sleepy
- Confusion: confused, overwhelmed, lost, uncertain, stuck
- Shame: ashamed, embarrassed, humiliated, guilty
- Problems: "I'm dealing with X", "my problem is X", "I can't X"
- Goals: "I want to X", "I'm trying to X", "my goal is X"
- Relationships: "my partner/boss/friend", "relationship issues"
- Work: "work stress", "my boss", "career change"
- Past: "when I was younger", "growing up", "I used to X"
- Communication: "I prefer X", "I don't like X", "I'm comfortable with X"
- Boundaries: "don't want to talk about X", "I'd rather not"
- Therapy Style: "I respond well to X", "what works for me is X"
The AI asks learning questions after the first message with 40% probability:
- "What do you do for work or study?"
- "Where are you based?"
- "Do you have any pets?"
- "What are your hobbies?"
- "Do you have a partner or kids?"
- "How old are you?"
- "Are you currently in school?"
- "What do you hope to get out of therapy?"
- "What's been on your mind lately?"
- "How would you describe your living situation?"
- "What does a typical day look like for you?"
- "Are you more of an introvert or extrovert?"
- "Is there a relationship you'd like to work on?"
- "How do you usually cope with difficult emotions?"
- "Do you prefer concrete advice or just someone to listen?"
- "What's one thing that always makes you smile?"
- "Are you a morning person or night owl?" ...and more
- Row Level Security (RLS) - Users can only access their own data (when enabled)
- Input Sanitization - Messages are sanitized before processing
- No Medical Advice - AI is instructed not to diagnose or replace professional care
- Privacy-First - Memories are stored per-user with RLS protection
MIT License
- AI Model: Google Gemini 2.5 Flash
- Database: Supabase
- Auth: Firebase
- UI Components: Shadcn UI + Tailwind CSS
- Charts: Recharts