olaf-voice 0.1.0
Real-time voice call interface for AI assistants
License: MIT
Requires Python: >=3.10

# Olaf Voice 🎙️

**Real-time voice call interface for AI assistants**

Have natural voice conversations with your AI assistant through a sleek, browser-based interface. Think "phone call with your AI" — speak naturally, get instant voice responses, and enjoy ambient background music while you chat.

![Demo](https://img.shields.io/badge/status-beta-blue)
![Python](https://img.shields.io/badge/python-3.10%2B-blue)
![License](https://img.shields.io/badge/license-MIT-green)

## ✨ Features

- 🎤 **Real-time voice interaction** — speak and hear responses instantly
- 🎨 **Clean, dark UI** — minimal, elegant interface designed for voice-first interaction
- 🎵 **Ambient background music** — lo-fi tones that auto-duck when Olaf speaks
- 🎙️ **Dual input modes** — Voice Activity Detection (VAD) or Push-to-Talk (PTT)
- 🏃 **Running mode** — simplified UI with larger controls for hands-free use
- 📊 **Live waveform visualizer** — see who's speaking in real-time
- 🔌 **OpenAI-compatible APIs** — works with OpenAI, OpenClaw proxy, or any compatible endpoint
- ⚙️ **Fully configurable** — customize voices, models, music, and behavior

## 📸 Screenshots

### Main Interface
Clean, centered call button with waveform visualizer and status display.

### Running Mode
Simplified interface with larger controls, perfect for hands-free use while exercising or driving.

## 🚀 Quick Start

### Installation

```bash
# Install from PyPI
pip install olaf-voice

# Or with uv (recommended)
uv pip install olaf-voice
```

### Basic Usage

```bash
# Set your OpenAI API key
export OLAF_VOICE_OPENAI_API_KEY="your-api-key"

# Start the server
olaf-voice

# Open browser to http://localhost:8765
```

That's it! Click the green call button and start talking.

## 🛠️ Configuration

### Environment Variables

```bash
# Server settings
export OLAF_VOICE_HOST="0.0.0.0"
export OLAF_VOICE_PORT="8765"

# OpenAI API
export OLAF_VOICE_OPENAI_API_KEY="sk-..."
export OLAF_VOICE_OPENAI_BASE_URL="https://api.openai.com/v1"  # optional

# Models
export OLAF_VOICE_WHISPER_MODEL="whisper-1"
export OLAF_VOICE_TTS_MODEL="tts-1"
export OLAF_VOICE_TTS_VOICE="alloy"  # alloy, echo, fable, onyx, nova, shimmer
export OLAF_VOICE_AI_MODEL="gpt-4o"

# Audio preferences
export OLAF_VOICE_VAD_ENABLED="true"
export OLAF_VOICE_MUSIC_VOLUME="0.3"
```

### YAML Configuration

Generate an example config file:

```bash
olaf-voice --generate-config config.yaml
```

Edit `config.yaml`:

```yaml
# Server
host: 0.0.0.0
port: 8765

# API Keys
openai_api_key: sk-...
openai_base_url: null  # Use default OpenAI, or set custom endpoint

# STT (Speech-to-Text)
whisper_model: whisper-1
whisper_language: null  # Auto-detect, or set 'en', 'es', etc.

# TTS (Text-to-Speech)
tts_model: tts-1
tts_voice: alloy
tts_speed: 1.0

# AI Model
ai_model: gpt-4o
ai_system_prompt: "You are Olaf, a helpful AI assistant..."
ai_max_tokens: 500
ai_temperature: 0.7

# Audio
vad_enabled: true
vad_sensitivity: 0.5
music_volume: 0.3
music_duck_volume: 0.1
```

Run with config:

```bash
olaf-voice --config config.yaml
```

### Command-Line Options

```bash
olaf-voice --help

# Start with custom host/port
olaf-voice --host 127.0.0.1 --port 9000

# Enable verbose logging
olaf-voice --verbose

# Use config file
olaf-voice --config /path/to/config.yaml
```

## 🎯 Usage Guide

### Starting a Call

1. Open http://localhost:8765 in your browser
2. Click the green **Call** button
3. Grant microphone permissions when prompted
4. Start talking!

### Controls

- **Mute** 🎤 — Temporarily mute your microphone
- **Music** 🎵 — Toggle background ambient music
- **VAD/PTT** 🎙️ — Switch between Voice Activity Detection and Push-to-Talk
  - **VAD mode** (default): Automatically detects when you're speaking
  - **PTT mode**: Hold SPACE to talk, release to send
- **Running** 🏃 — Toggle simplified UI for hands-free use
- **Volume slider** — Adjust output volume

### Keyboard Shortcuts

- **SPACE** — Push-to-talk (when in PTT mode)
- Click controls to toggle features

### Running Mode

Perfect for when you're exercising, driving, or want a simplified experience:

1. Click the **Running** 🏃 button
2. UI simplifies to just:
   - Large call button
   - Status display
   - Transcript (shows conversation)

Press **Running** again to return to full interface.

## 🏗️ Architecture

```
┌─────────────┐      WebSocket      ┌──────────────┐
│   Browser   │ ◄─────────────────► │  FastAPI     │
│             │                      │  Server      │
│ - Mic input │   Audio (base64)    │              │
│ - Speaker   │ ──────────────────► │ - Whisper    │
│ - Visualizer│                      │ - AI Chat    │
│ - Controls  │ ◄────────────────── │ - TTS        │
└─────────────┘   Audio + Text      └──────────────┘
```

### Flow

1. **Capture**: Browser captures microphone audio (WebM format)
2. **Send**: Audio sent via WebSocket as base64
3. **Transcribe**: Backend uses OpenAI Whisper API to convert speech to text
4. **Think**: Text sent to AI model (GPT-4, etc.) for response
5. **Synthesize**: AI response converted to speech via TTS API
6. **Play**: Audio streamed back to browser and played

### Background Music

Ambient lo-fi music is generated client-side using Web Audio API oscillators and filters — no audio files needed! The music automatically "ducks" (reduces volume) when Olaf is speaking, then returns to normal.

## 🧪 Development

### Setup

```bash
# Clone repository
git clone https://github.com/Olafs-World/olaf-voice.git
cd olaf-voice

# Install with dev dependencies
uv pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=olaf_voice --cov-report=html
```

### Project Structure

```
olaf-voice/
├── src/olaf_voice/
│   ├── __init__.py          # Package exports
│   ├── __main__.py          # CLI entry point
│   ├── config.py            # Configuration management
│   ├── server.py            # FastAPI server + WebSocket
│   ├── transcribe.py        # Whisper STT integration
│   ├── tts.py              # OpenAI TTS integration
│   ├── ai.py               # AI chat integration
│   └── static/
│       ├── index.html       # Main UI
│       ├── style.css        # Styling
│       └── app.js          # Client-side logic
├── tests/                   # Pytest tests
├── pyproject.toml          # Package metadata
└── README.md
```

### Running Tests

```bash
# Run all tests
pytest

# Run specific test file
pytest tests/test_config.py

# Run with coverage
pytest --cov=olaf_voice

# Verbose output
pytest -v
```

### Code Quality

```bash
# Format code
black src/ tests/

# Lint
ruff check src/ tests/

# Type check
mypy src/
```

## 🐛 Troubleshooting

### Microphone not working

1. Check browser permissions — look for 🎤 icon in address bar
2. Ensure HTTPS or localhost (mic requires secure context)
3. Try a different browser (Chrome/Edge recommended)

### WebSocket connection fails

1. Check firewall settings
2. Verify port 8765 (or custom port) is not in use
3. Check browser console for errors

### No audio playback

1. Check volume slider in the app
2. Verify system volume is not muted
3. Check browser's autoplay policies (click UI first to enable audio)

### API errors

1. Verify `OLAF_VOICE_OPENAI_API_KEY` is set correctly
2. Check API quota and billing status
3. Enable verbose logging: `olaf-voice --verbose`

### High latency

- Use `tts-1` model (faster than `tts-1-hd`)
- Reduce `ai_max_tokens` for shorter responses
- Use a faster AI model (e.g., `gpt-4o-mini`)

## 🤝 Contributing

Contributions welcome! Please:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit changes (`git commit -m 'Add amazing feature'`)
4. Push to branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📝 License

MIT License - see [LICENSE](LICENSE) for details.

## 🙏 Credits

Built with:
- [FastAPI](https://fastapi.tiangolo.com/) — Modern web framework
- [OpenAI APIs](https://platform.openai.com/) — Whisper, TTS, GPT
- [Web Audio API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) — Browser audio processing

## 📬 Support

- **Issues**: [GitHub Issues](https://github.com/Olafs-World/olaf-voice/issues)
- **Discussions**: [GitHub Discussions](https://github.com/Olafs-World/olaf-voice/discussions)

---

**Made with ❤️ for seamless AI conversations**