Overview
Echoes of the Past uses Vapi for real-time voice conversations with historical figures. The integration includes:- Voice synthesis via ElevenLabs
- Speech recognition for user input
- Real-time transcription and message streaming
- Audio level monitoring for visual feedback
- Assistant configuration with OpenAI models
Vapi SDK Setup
The Vapi client is initialized inlib/vapi.ts:
lib/vapi.ts
.env.local
useVapi Hook
TheuseVapi hook encapsulates all Vapi integration logic:
Hook Interface
features/call/hooks/useVapi.ts
Assistant Configuration
The assistant object defines the AI’s behavior, voice, and model:features/call/hooks/useVapi.ts
Voice Configuration Parameters
Voice Configuration Parameters
ElevenLabs voice settings:
voiceId: Character-specific voice from ElevenLabsstability: 0-1, higher = more consistent but less expressive (0.4 recommended)similarityBoost: 0-1, higher = closer to original voice (0.8 recommended)speed: Playback speed multiplier (1 = normal)style: 0-1, voice style intensity (0.5 = balanced)useSpeakerBoost: Enhances clarity for different speakers
- Lower stability (0.3-0.5) for more dynamic conversations
- Higher stability (0.6-0.8) for formal or educational content
- Adjust
speedbased on character personality (slower for contemplative figures)
Message Plan Configuration
Message Plan Configuration
Idle message behavior:Purpose: Keeps conversation engaging without being annoying. After user speaks, idle counter resets.
Event Handling
Vapi emits events throughout the call lifecycle:Event Listeners Setup
features/call/hooks/useVapi.ts
Event Types Reference
- speech-start / speech-end
- call-start / call-end
- volume-level
- message
Purpose: Track when AI assistant is speakingUse cases:
- Show “speaking” indicator
- Animate avatar
- Disable input during AI speech
Call Control Methods
Starting a Call
features/call/hooks/useVapi.ts
Stopping a Call
Toggle Call State
Programmatic Messages
Send system messages to the assistant during a call:features/call/hooks/useVapi.ts
Real-Time Transcription
Message Types
types/conversation.type.ts
Displaying Transcripts
features/call/components/chat-view.tsx
- Renders completed messages from
messagesarray - Shows live
activeTranscriptwith visual indicator (e.g., typing dots) - Distinguishes between user and assistant messages
- Auto-scrolls to latest message
Call Interface Example
Complete implementation of a voice call UI:features/call/components/call-interface.tsx
Webhook Configuration
For server-side message processing, configure a webhook endpoint:app/api/webhook/route.ts
Best Practices
Event Cleanup
Event Cleanup
Always clean up event listeners to prevent memory leaks:Missing cleanup causes:
- Duplicate event handlers
- Memory leaks
- Stale state references
Call State Management
Call State Management
Use LOADING state during transitions:Prevents:
- Multiple simultaneous calls
- Button spam
- Race conditions
Audio Level Throttling
Audio Level Throttling
Throttle volume-level updates for performance:Volume events fire very frequently; throttling prevents excessive re-renders.
Troubleshooting
- No Audio Output
- Transcription Issues
- Call Won't Start
Symptoms: Call connects but no voice heardChecklist:
- Verify
voiceIdis valid ElevenLabs voice - Check browser audio permissions
- Ensure
NEXT_PUBLIC_VAPI_WEB_TOKENis set - Test with different voice settings (adjust stability/speed)
- Check browser console for WebRTC errors
Related Documentation
- Prompt Engineering - Crafting effective system prompts
- Feature Structure - How call feature is organized