MoodLens - Voice AI Mood Journal
A voice-first mood journaling application and emotional companion.
Recipe prompt
Paste into Cursor, Claude Code, v0, or your coding agentYou are implementing the "MoodLens - Voice AI Mood Journal" recipe in this project.
Read the recipe markdown first:
https://raw.githubusercontent.com/sandy10/voice_ai_agent/main/docs/ai/RECIPE.md
Use the source repository for cross-reference:
https://github.com/sandy10/voice_ai_agent
Build this recipe into the user's app using the markdown as the implementation guide. Inspect related source files through the repository links when the recipe points to them. Ask before installing new dependencies.Recipe
Rendered from the configured recipe markdown.
MoodLens - AI Voice Mood Journal
MoodLens is a voice-first mood journaling application and emotional companion built on top of the Agora Conversational AI platform. Instead of typing out how you feel, users simply talk about their day with an empathetic AI companion. As they speak, the app listens, analyzes their emotions, and visualizes their mood in real-time.
This recipe demonstrates how to combine Agora RTC, Jetpack Compose Custom Graphics, and On-device sentiment analysis into a seamless, interactive Android app.
🎯 Use Case
Traditional journaling apps suffer from high friction—users have to type out their thoughts after a long day. Voice assistants are typically transactional ("Set a timer"). This project bridges the gap by creating an AI companion that:
- Actively listens via low-latency voice AI.
- Infers emotional state in real-time directly from the streaming transcript.
- Provides immediate visual and conversational feedback.
🏗️ Architecture & Key Components
This project is split into a Python Backend and a Kotlin Android Client.
Backend (Agora TEN Framework)
The backend acts as the orchestrator. It connects to the Agora channel and bridges the gap between:
- Speech-to-Text (Nova-3)
- LLM (GPT-4o-mini)
- Text-to-Speech (MiniMax)
The backend is completely stateless and can be hosted on platforms like Render. It handles the heavy lifting of the conversational AI so the Android device is free to focus on UI and local sentiment analysis.
Android Client (Jetpack Compose)
The Android app is responsible for the user interface, joining the Agora channel, and locally analyzing the conversation.
1. Real-Time Transcript & Sentiment Analysis
As the user speaks, the Agora SDK receives real-time transcription events (user.transcription and assistant.transcription) via the RTM (Real-Time Messaging) channel.
The app takes these transcripts and feeds them into the MoodAnalyzer, which uses keyword matching and an Exponential Moving Average (EMA) algorithm to smoothly transition the user's emotional state over time.
// MoodAnalyzer.kt
fun analyzeIncremental(previousSnapshot: MoodSnapshot, newTurnText: String): MoodSnapshot {
val newSnapshot = analyzeTranscript(listOf(newTurnText)) // Keyword matching
// EMA Smoothing for fluid UI transitions
val alpha = 0.4f
val oneMinusAlpha = 1f - alpha
val joy = (previousSnapshot.joy * oneMinusAlpha) + (newSnapshot.joy * alpha)
// ... calculate for calm, energy, stress, sadness
val blendedSnapshot = MoodSnapshot(joy = joy, calm = calm, ...)
return blendedSnapshot.copy(dominantMood = blendedSnapshot.dominantDimension())
}2. Dynamic UI Visualizations
The MoodRingCanvas.kt component takes the MoodSnapshot flow and dynamically animates concentric rings. Each emotion corresponds to a specific color and ring size. As the EMA-smoothed scores update, the rings breathe and pulse, giving the user an intuitive sense of their emotional landscape.
3. Local Data Persistence
For privacy, all journal entries are stored strictly on the user's device. When a session ends, the app packages the final MoodSnapshot and a summary of the transcript into a MoodEntry and saves it using Gson and encrypted SharedPreferences.
🚀 How to Run
1. Prerequisites
- Android Studio Ladybug or newer.
- An Agora Developer Account (App ID and App Certificate).
- (Optional) A Render account if you wish to deploy the backend yourself, otherwise you can use the provided quickstart server.
2. Configure the Android App
The Android app is pre-configured to connect to a live quickstart server. Ensure your local.properties file in the Android root directory points to the live backend (or your own deployed backend):
QUICKSTART_SERVER_URL=https://agora-voice-agent.onrender.com3. Build & Run
Open the voice_ai_agent folder in Android Studio, sync Gradle, and run the app on an emulator or physical device.
4. Running your own Backend
If you wish to modify the AI's behavior, prompt, or services, you can run the Python backend locally:
- Navigate to the
server/directory. - Set up your virtual environment and run
pip install -r requirements.txt. - Add your Agora App ID, App Certificate, and API keys to the
.envfile. - Run the server using uvicorn:
``bash python -m uvicorn app.main:app --reload --host 127.0.0.1 ``
- Point your Android app's
QUICKSTART_SERVER_URLtohttp://localhost:8000(Useadb reverse tcp:8000 tcp:8000to expose localhost to your emulator/device).