Project Info
The
Inspiration
In a world of constant digital noise, our phones have become sources of disruption. Between relentless marketing calls, promotional spam, and the anxiety of "unknown numbers," we are losing our most valuable asset: focus. As a developer and an introvert, I realized that many of us face major hurdles: The Noise: Endless random calls that break our deep work. The Social Drain: The mental energy required for "small-talk" errands when we just want to stay focused on what matters. The Broadcast Burden: The difficulty of sharing information with many people simultaneously without losing hours to manual calling. The Memory Gap: Trying to recall exactly what was discussed in a call weeks or months ago. I was inspired to build AI Phone — a "Communication Shield" that doesn't just transcribe, but acts as your professional double. It makes and receives calls on your behalf, remembers every detail, and resolves errands while you live your life. What It Does AI Phone is a full-stack mobile application that delegates phone calls to an intelligent AI agent. At its core, it offers: Real-Time AI Voice Calls Initiate outbound calls through natural language missions ("Call my dentist and reschedule my appointment") AI speaks naturally using Gemini's Multimodal Live API with voice synthesis Bidirectional audio streaming with real-time transcription Automatic call completion with AI-generated summaries Customizable AI Agents Create multiple AI personas with distinct personalities Choose from 10 unique voice profiles: Aoede (casual), Charon (professional), Kore (calm), Fenrir (energetic), Leda (youthful), Orus (authoritative), Puck (playful), Zephyr (breeze), Vale (warm), Sage (British accent) Configure tone, behavior guidelines, and caller information Set language restrictions (single or multi-language support) Designate a primary agent for quick calls Context-Aware Memory Every call is transcribed and stored with a structured summary AI can access previous conversations with the same contact Ask your AI: "What did we discuss last time?" — it knows Knowledge Base Chat Chat interface to query your entire call history Gemini-powered RAG (Retrieval-Augmented Generation) for intelligent answers Referenced calls displayed alongside responses Unified Call Log Seamlessly merges AI calls with your device's native call history Contact integration with fast Trie-based search Filter by call type (AI vs. Device) How I Built It The project is built on an industrial-grade, full-stack architecture designed for real-time interaction: Architecture Overview Backend (The Engine) I used Serverpod as the backbone. Its Dart-first ORM and high-performance capabilities allowed me to build a seamless bridge between the database and the telephony logic. Key services include: MediaStreamHandler: Bidirectional WebSocket bridge between Twilio and Gemini AudioTranscoder: Real-time μ-law ↔ PCM conversion with upsampling/downsampling GeminiLiveService: Manages WebSocket connections to Gemini's real-time API CallSchedulerService: Handles scheduled calls via Serverpod's FutureCalls CallEventService: WebSocket broadcasting for live UI updates The Intelligence Gemini 2.5 Flash serves as the reasoning core via the Multimodal Live API. Using a RAG (Retrieval-Augmented Generation) system, I gave the AI a long-term memory by storing call histories in a PostgreSQL database. The AI has access to tool functions: get_call_history() — Retrieve previous conversations with the same contact end_call(reason, summary) — Autonomously terminate calls when mission complete Telephony Twilio Programmable Voice handles the global telephony infrastructure: REST API for call initiation with TwiML webhooks Media Streams for bidirectional audio via WebSocket Automatic call recording with MP3 storage Status callbacks for real-time call state tracking Frontend A clean Flutter interface with Riverpod state management across 12 screens: DialerScreen: Contact integration with Trie-based search CallAgentsScreen: Create and manage AI personas ActiveCallMonitorScreen: Live transcript and status updates CallHistoryScreen: Unified AI + device call log ChatScreen: Knowledge base queries with referenced calls Challenges I Faced: Mastering the Conversation Challenge 1: The Audio Mismatch The most significant hurdle was the Audio Format Gap. Telephony standards operate at 8,000 Hz μ-law (Narrowband), while Gemini requires high-fidelity PCM at 16,000 Hz for input and outputs at 24,000 Hz. Solution — Custom Audio Transcoder: I built a real-time audio transcoding pipeline with: Pre-computed μ-law decode/encode tables (256 entries) for O(1) conversion Linear interpolation for upsampling (8kHz → 16kHz) 3:1 averaging for downsampling (24kHz → 8kHz) 20ms audio chunks (~200 bytes) processed in real-time Challenge 2: The Latency Paradox For conversations to feel natural, the AI's first response must arrive in under 3 seconds. Initial tests showed 5+ second delays. Solution — Gemini Pre-initialization: Instead of waiting for Twilio to connect before initializing Gemini, I start the Gemini WebSocket connection during call setup. By the time the recipient answers, the AI is ready to speak. Challenge 3: Transcript Persistence Real-time transcripts were being lost when calls ended abruptly. The solution involved: Debounced database updates (500ms) to avoid excessive writes Saving transcript before broadcasting status changes FutureCall-based post-call analysis with 5-second delay Challenge 4: Memory Retrieval at Scale The AI needs instant access to call history for context-aware conversations: [ T(n) = O(\log n) ] By optimizing PostgreSQL indexes on (userId, phoneNumber, completedAt), the AI retrieves relevant history from thousands of calls in milliseconds. What I Learned I learned that the future of AI isn't about replacing human connection; it's about filtering the noise. Building this taught me: Technical Insights Real-time systems are unforgiving: Every millisecond matters. A 100ms delay in audio processing compounds into awkward pauses. State synchronization is hard: Coordinating state between Flutter, Serverpod, Twilio, and Gemini required careful event-driven architecture. Audio engineering is its own discipline: Understanding μ-law encoding, sample rates, and interpolation algorithms opened a new world. Product Insights Context is everything: An assistant that remembers previous conversations is infinitely more valuable than one that just talks. Voice UX differs from chat UX: Users expect immediate responses. Silence feels like failure. Customization breeds adoption: Letting users create their own AI personas with unique voices and behaviors dramatically increases engagement. Architecture Insights Dart everywhere works: Having Flutter, Serverpod, and shared models all in Dart eliminated entire categories of bugs. WebSocket > Polling: Real-time updates via WebSocket broadcasting transformed the user experience. Pre-computation pays off: Lookup tables for audio conversion, Trie structures for contact search — these optimizations compound. The Call Flow Here's how a typical AI call works end-to-end: Tech Stack Summary Future Roadmap AI Phone is just the beginning. The next 12 months will focus on: Near-Term (Q1-Q2) Inbound Call Handling: Let AI answer calls on your behalf with caller ID screening Call Transfer: Seamless handoff to human operator with full context Multi-party Broadcasts: Call multiple recipients with the same message Mid-Term (Q3-Q4) Emotional Intelligence: Adapt AI's tone based on caller's urgency or mood Autonomous Scheduling: Calendar integration to resolve booking conflicts automatically Advanced Analytics: Success metrics, failure analysis, conversation insights Long-Term (Year 2) Visual Context: AI can "see" documents or images shared during calls Language Expansion: Localized voice profiles for any language or dialect Barge-in Detection: Allow user to interrupt and take over mid-call Project Statistics The Impact AI Phone is for the busy professional, the introvert, and anyone tired of the noise. Whether you need to: Handle a tedious customer service call while you focus on work Follow up with leads without the mental drain of repetitive conversations Schedule appointments while your AI remembers all the details Query your call history — "What did the insurance company say last month?" AI Phone ensures you can reclaim your time and stay focused on what actually matters. Try It Yourself The project demonstrates: Full-stack Dart development (Flutter + Serverpod) Real-time WebSocket communication Audio engineering with format transcoding AI integration with tool calling Production-grade state management Built with passion for developers who value their focus.
About
AI Phone is a full-stack mobile application that delegates phone calls to an intelligent AI agent. Give it a mission like "Call my dentist and reschedule my appointment" — the AI makes the call, has a natural conversation, and reports back with a summary.
Key Features
- AI Voice Calls — AI makes real phone calls and speaks naturally
- Live Transcription — Watch the conversation in real-time
- Call Memory — AI remembers previous conversations with the same contact
- Custom AI Agents — Create personas with different voices and personalities
- 10 Voice Options — Professional, casual, energetic, calm, and more
- Scheduled Calls — Set calls to happen at a specific time
- Call History Search — Ask questions about past calls in plain English
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Flutter Mobile App │
│ (Riverpod State Management • 12 Screens • Contact Integration)│
└─────────────────────────┬───────────────────────────────────────┘
│ REST + WebSocket
┌─────────────────────────▼───────────────────────────────────────┐
│ Serverpod Backend │
│ (Dart-first ORM • Real-time Streams • FutureCalls Scheduling) │
└───────────┬─────────────────────────────────────────────────────┘
│
┌───────┴───────┐
│ │
┌───▼───┐ ┌───▼───────────────────┐
│Twilio │◀─────▶│ Gemini Live API │
│ Voice │ Audio │ (Speech-to-Speech AI) │
└───────┘ Bridge└───────────────────────┘
Tech Stack
| Component | Technology |
|---|---|
| Mobile App | Flutter 3.32 |
| State Management | Riverpod 2.5 |
| Backend | Serverpod 3.2 |
| Database | PostgreSQL |
| AI Engine | Gemini 2.5 Flash (Multimodal Live API) |
| Telephony | Twilio Programmable Voice |
| Real-time | WebSocket |
Project Structure
phone_ai/
├── phone_ai_flutter/ # Flutter mobile app
│ ├── lib/
│ │ ├── screens/ # UI screens (12 screens)
│ │ ├── providers/ # Riverpod state management
│ │ ├── widgets/ # Reusable components
│ │ └── constants/ # App constants
│ └── pubspec.yaml
│
├── phone_ai_server/ # Serverpod backend
│ ├── lib/src/
│ │ ├── services/ # Core services
│ │ │ ├── gemini_live_service.dart
│ │ │ ├── twilio_service.dart
│ │ │ └── audio_transcoder.dart
│ │ ├── websocket/ # WebSocket handlers
│ │ ├── calls/ # Call endpoints
│ │ └── web/routes/ # HTTP routes
│ └── config/
│ └── passwords.yaml # Credentials (not in git)
│
├── phone_ai_client/ # Generated client code
└── docs/ # Documentation
└── passwords.sample.yaml # Sample credentials file
Prerequisites
Before running the project, you need:
- Flutter SDK (3.32+)
- Dart SDK (3.0+)
- Docker (for PostgreSQL and Redis)
- ngrok (for local development webhooks)
- Twilio Account — Get one here
- Google AI API Key — Get one here
Setup Instructions
Step 1: Clone the Repository
git clone https://github.com/yourusername/phone_ai.git
cd phone_ai
Step 2: Set Up Credentials
-
Copy the sample credentials file:
cp docs/passwords.sample.yaml phone_ai_server/config/passwords.yaml -
Edit
phone_ai_server/config/passwords.yamland fill in your credentials:Twilio (from console.twilio.com):
twilio_account_sid— Your Account SID (starts with 'AC')twilio_auth_token— Your Auth Tokentwilio_phone_number— Your Twilio phone number (E.164 format: +1234567890)
Gemini (from ai.google.dev):
gemini_api_key— Your API key
Webhook URL — See Step 4
Step 3: Start the Database
cd phone_ai_server
docker compose up -d
This starts PostgreSQL and Redis containers.
Step 4: Set Up ngrok (for Twilio webhooks)
Twilio needs to reach your local server via a public URL. ngrok creates a tunnel.
-
Install ngrok:
# macOS brew install ngrok # Or download from https://ngrok.com/download -
Start ngrok:
ngrok http 8085 -
Copy the HTTPS URL (e.g.,
https://abc123.ngrok-free.app) -
Update passwords.yaml:
webhook_base_url: 'https://abc123.ngrok-free.app'Important: Every time you restart ngrok, you get a new URL. Update
passwords.yamlaccordingly.
Step 5: Start the Backend Server
cd phone_ai_server
dart bin/main.dart
The server runs on http://localhost:8080 (API) and http://localhost:8085 (Web/Webhooks).
Step 6: Run the Flutter App
cd phone_ai_flutter
flutter pub get
flutter run
Running in Development
Here's the typical development workflow:
Terminal 1: Database
cd phone_ai_server
docker compose up
Terminal 2: ngrok
ngrok http 8085
# Copy the URL and update passwords.yaml
Terminal 3: Backend Server
cd phone_ai_server
dart bin/main.dart
Terminal 4: Flutter App
cd phone_ai_flutter
flutter run
Configuration Reference
passwords.yaml
| Key | Description | Where to Get It |
|---|---|---|
twilio_account_sid | Twilio Account SID | Twilio Console |
twilio_auth_token | Twilio Auth Token | Twilio Console |
twilio_phone_number | Your Twilio phone number | Twilio Console > Phone Numbers |
webhook_base_url | Public URL for webhooks | ngrok or your server domain |
gemini_api_key | Google AI API key | Google AI Studio |
gemini_live_model | Model for voice calls | Default: gemini-2.5-flash-preview-native-audio-dialog |
gemini_analysis_model | Model for summaries | Default: gemini-2.5-pro |
Twilio Setup
- Create a Twilio account at twilio.com
- Get a phone number with Voice capability
- Your webhooks will be automatically configured when calls are initiated
ngrok Tips
- Free tier works fine for development
- Keep ngrok running while testing calls
- Update webhook_base_url every time ngrok restarts (new URL each time)
- For persistent URLs, consider ngrok paid plans or deploy to a server
Troubleshooting
"No audio from AI"
- Check that
webhook_base_urlin passwords.yaml matches your current ngrok URL - Ensure ngrok is running:
ngrok http 8085 - Check server logs for errors
"Call fails to connect"
- Verify Twilio credentials are correct
- Check that your Twilio phone number has Voice capability
- Ensure the destination number is in E.164 format (+1234567890)
"Gemini connection error"
- Verify your Gemini API key is valid
- Check that the model names are correct
- Ensure you have API access to the Multimodal Live API
"Database connection error"
- Make sure Docker is running:
docker compose up -d - Check PostgreSQL logs:
docker compose logs postgres
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/call/initiateCall | POST | Start a new AI call |
/call/getCallStatus | GET | Get call status by ID |
/call/getCallHistory | GET | Get user's call history |
/twilio/voice | POST | Twilio webhook for call setup |
/twilio/status | POST | Twilio status callbacks |
/media-stream | WebSocket | Bidirectional audio stream |
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'Add my feature' - Push to the branch:
git push origin feature/my-feature - Open a Pull Request
License
This project is licensed under the MIT License.
Acknowledgments
- Serverpod — Dart-first backend framework
- Twilio — Programmable voice infrastructure
- Google Gemini — Multimodal AI capabilities
- Flutter — Cross-platform app framework
Analysis
View
Metric
No commits on this project resolved to a GitHub account.
Technology
- CIn code
- C++In code
- CSSIn code
- DartIn code
- HTMLIn code
- KotlinIn code
- SQLIn code
- SwiftIn code
8 of 8 appear in the indexed code.
AI coding agents
- Claude CodeConfig
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
1.0 MB
Source files
171
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
kanakapalli/phone_ai
304 files · 4.8 MB · @ 68bcef4
Structure
Interface
28 files · 9%Screens, components and styles rendered to the user.
API & routing
4 files · 1%Request entry points: routes, handlers and controllers.
Application logic
137 files · 45%Domain rules, services and shared utilities.
+7 moreData & schema
30 files · 10%Schema definitions, migrations and data access.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Dart70%
- SQL15%
- Markdown8%
- YAML3%
- C++2%
- C1%
- Other (5)2%
Share of indexed source by file size. Binary and vendored files are excluded.
This project’s features have not been analysed yet.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.