Metadata-Version: 2.4
Name: talky
Version: 0.1.1
Summary: Talky voice AI
License-Expression: MIT
Requires-Python: <3.13,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.0.0
Requires-Dist: loguru>=0.7.3
Requires-Dist: pipecat-ai[runner,silero,webrtc]==0.0.102
Requires-Dist: fastmcp>=2.0.0
Requires-Dist: fastapi
Requires-Dist: uvicorn
Requires-Dist: mcp>=1.0.0
Requires-Dist: httpx<1,>=0.28.0
Requires-Dist: python-dotenv<2,>=1.0.0
Requires-Dist: requests<3,>=2.32.5
Requires-Dist: InquirerPy>=0.3.4
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
Requires-Dist: kokoro-onnx<1,>=0.5.0
Requires-Dist: pipecat-ai[cartesia,deepgram,google,local-smart-turn-v3,rnnoise,websocket]==0.0.102
Requires-Dist: pipecat-ai[mlx-whisper]==0.0.102; sys_platform == "darwin"
Requires-Dist: pipecat-ai[whisper]==0.0.102; sys_platform != "darwin"
Requires-Dist: pyobjc-framework-CoreMedia>=11.0; sys_platform == "darwin"
Requires-Dist: pyobjc-framework-Quartz>=11.0; sys_platform == "darwin"
Requires-Dist: pyobjc-framework-ScreenCaptureKit>=11.0; sys_platform == "darwin"
Requires-Dist: python-xlib>=0.33; sys_platform == "linux"
Provides-Extra: local-audio
Requires-Dist: pyaudio; extra == "local-audio"
Provides-Extra: audio
Requires-Dist: pyaudio; extra == "audio"
Provides-Extra: tts-openai
Requires-Dist: pipecat-ai[openai]; extra == "tts-openai"
Provides-Extra: tts-elevenlabs
Requires-Dist: pipecat-ai[elevenlabs]; extra == "tts-elevenlabs"
Provides-Extra: tts-cartesia
Requires-Dist: pipecat-ai[cartesia]; extra == "tts-cartesia"
Provides-Extra: tts-fish
Requires-Dist: pipecat-ai[fish]; extra == "tts-fish"
Provides-Extra: tts-gradium
Requires-Dist: pipecat-ai[gradium]; extra == "tts-gradium"
Provides-Extra: tts-hume
Requires-Dist: pipecat-ai[hume]; extra == "tts-hume"
Provides-Extra: tts-lmnt
Requires-Dist: pipecat-ai[lmnt]; extra == "tts-lmnt"
Provides-Extra: tts-neuphonic
Requires-Dist: pipecat-ai[neuphonic]; extra == "tts-neuphonic"
Provides-Extra: tts-nvidia
Requires-Dist: pipecat-ai[nvidia]; extra == "tts-nvidia"
Provides-Extra: tts-playht
Requires-Dist: pipecat-ai[playht]; extra == "tts-playht"
Provides-Extra: tts-resembleai
Requires-Dist: pipecat-ai[resembleai]; extra == "tts-resembleai"
Provides-Extra: tts-rime
Requires-Dist: pipecat-ai[rime]; extra == "tts-rime"
Provides-Extra: tts-sambanova
Requires-Dist: pipecat-ai[sambanova]; extra == "tts-sambanova"
Provides-Extra: tts-sarvam
Requires-Dist: pipecat-ai[sarvam]; extra == "tts-sarvam"
Provides-Extra: tts-kokoro
Requires-Dist: pipecat-ai[kokoro]; extra == "tts-kokoro"
Provides-Extra: stt-assemblyai
Requires-Dist: pipecat-ai[assemblyai]; extra == "stt-assemblyai"
Provides-Extra: stt-asyncai
Requires-Dist: pipecat-ai[asyncai]; extra == "stt-asyncai"
Provides-Extra: stt-deepgram
Requires-Dist: pipecat-ai[deepgram]; extra == "stt-deepgram"
Provides-Extra: stt-fish
Requires-Dist: pipecat-ai[fish]; extra == "stt-fish"
Provides-Extra: stt-gladia
Requires-Dist: pipecat-ai[gladia]; extra == "stt-gladia"
Provides-Extra: stt-google
Requires-Dist: pipecat-ai[google]; extra == "stt-google"
Requires-Dist: google-genai; extra == "stt-google"
Provides-Extra: stt-hume
Requires-Dist: pipecat-ai[hume]; extra == "stt-hume"
Provides-Extra: stt-inworld
Requires-Dist: pipecat-ai[inworld]; extra == "stt-inworld"
Provides-Extra: stt-nvidia
Requires-Dist: pipecat-ai[nvidia]; extra == "stt-nvidia"
Provides-Extra: stt-openai
Requires-Dist: pipecat-ai[openai]; extra == "stt-openai"
Provides-Extra: stt-resembleai
Requires-Dist: pipecat-ai[resembleai]; extra == "stt-resembleai"
Provides-Extra: stt-sarvam
Requires-Dist: pipecat-ai[sarvam]; extra == "stt-sarvam"
Provides-Extra: stt-soniox
Requires-Dist: pipecat-ai[soniox]; extra == "stt-soniox"
Provides-Extra: stt-speechmatics
Requires-Dist: pipecat-ai[speechmatics]; extra == "stt-speechmatics"
Provides-Extra: stt-whisper-local
Requires-Dist: pipecat-ai[mlx-whisper]; extra == "stt-whisper-local"
Provides-Extra: aws
Requires-Dist: pipecat-ai[aws]; extra == "aws"
Provides-Extra: azure
Requires-Dist: pipecat-ai[azure]; extra == "azure"
Provides-Extra: fal
Requires-Dist: pipecat-ai[fal]; extra == "fal"
Provides-Extra: groq
Requires-Dist: pipecat-ai[groq]; extra == "groq"
Provides-Extra: claude-code
Requires-Dist: claude-code-sdk==0.0.25; extra == "claude-code"
Provides-Extra: opencode
Requires-Dist: opencode-ai>=0.1.0a36; extra == "opencode"
Requires-Dist: httpx>=0.27; extra == "opencode"
Provides-Extra: tts
Requires-Dist: pipecat-ai[cartesia,elevenlabs,fish,gradium,hume,kokoro,lmnt,neuphonic,nvidia,openai,playht,resembleai,rime,sambanova,sarvam]; extra == "tts"
Provides-Extra: stt
Requires-Dist: pipecat-ai[assemblyai,asyncai,deepgram,fish,gladia,google,hume,inworld,mlx-whisper,nvidia,openai,resembleai,sarvam,soniox,speechmatics]; extra == "stt"
Provides-Extra: all
Requires-Dist: pyaudio; extra == "all"
Requires-Dist: pipecat-ai[assemblyai,asyncai,aws,azure,cartesia,deepgram,elevenlabs,fal,fish,gladia,google,gradium,groq,hume,inworld,kokoro,lmnt,mlx-whisper,neuphonic,nvidia,openai,playht,resembleai,rime,sambanova,sarvam,soniox,speechmatics]; extra == "all"
Dynamic: license-file

# Talky

Voice interface for AI. Talk to OpenClaw, Moltis, Hermes or Pi. Or use MCP to talk to Claude.

### Desktop

<a href="screenshots/talky%20convo.png" target="_blank">
  <img src="screenshots/talky%20convo.png" alt="Talky voice conversation" width="600">
</a>

<p>
  <a href="screenshots/talky%20profile%20picker.png" target="_blank">
    <img src="screenshots/talky%20profile%20picker.png" alt="Switch AI profile" width="290">
  </a>
  <a href="screenshots/talky%20voice%20picker.png" target="_blank">
    <img src="screenshots/talky%20voice%20picker.png" alt="Switch voice" width="290">
  </a>
</p>

### Mobile

<p>
  <a href="screenshots/talky%20mobile%20start.png" target="_blank">
    <img src="screenshots/talky%20mobile%20start.png" alt="Mobile start screen" width="180">
  </a>
  <a href="screenshots/talky%20mobile%20convo.png" target="_blank">
    <img src="screenshots/talky%20mobile%20convo.png" alt="Mobile conversation" width="180">
  </a>
  <a href="screenshots/talky%20mobile%20controls.png" target="_blank">
    <img src="screenshots/talky%20mobile%20controls.png" alt="Mobile controls" width="180">
  </a>
</p>

## Quick Start

**Requirements**: Python 3.12 or 3.13, [uv](https://docs.astral.sh/uv/), Homebrew

```bash
brew install portaudio                # required for local audio (talky say)
uv tool install talky                 # from PyPI, or: uv tool install --editable . (from source)
talky openclaw                    # Talk to OpenClaw
talky moltis                      # Talk to Moltis  
talky hermes                      # Talk to Hermes (NousResearch)
talky pi                          # Talk to Pi
talky say "Hello world"           # Test voice output
```

> **Install via `uv tool`, not `pip`.** Talky installs heavy LLM / TTS / STT
> dependencies on-demand via `uv tool install --with`. Plain `pip install talky`
> into system Python leaves the on-demand installer with nowhere to write, and
> it will refuse with an error.

## Usage

**Talk to AI**
- `talky openclaw` - OpenClaw assistant
- `talky moltis` - Moltis assistant  
- `talky hermes` - Hermes agent (NousResearch)
- `talky pi` - Pi coding assistant
- Opens browser at `localhost:9090` for voice chat

**Change Voice**
- `talky moltis -v kokoro-uk-george` - Use different voice
- `talky say "test" -v google-puck` - Test specific voice

**List Options**
- `talky ls` - See all available voices and profiles

**Daemon / MCP** (for Claude Desktop/Claude Code)
- `talky daemon` - Start the talky daemon (listens on 9090, serves browser UI + MCP tools)
- Any daemon-dependent command (e.g. `talky openclaw`) auto-spawns the daemon if it isn't running

## Documentation

- [Integrations](docs/integrations/) - Backend and platform integrations
- [Remote Access](docs/remote-access.md) - External network access setup
- [Voice Profiles](docs/voice-profiles.md) - Voice configuration options

**Setup**
- `talky config` - Create config files
- Add API keys to `~/.talky/credentials/` (one JSON file per provider)

> **Note:** The default voice profile uses local providers (kokoro TTS + whisper STT).
> These require `brew install portaudio` and will download ML models on first use.
> To avoid this, set a cloud voice profile in `~/.talky/settings.yaml` before running.

**Example API Keys**
```bash
# Deepgram (speech-to-text)
echo '{"api_key":"your-key"}' > ~/.talky/credentials/deepgram.json

# Google (text-to-speech)  
echo '{"credentials":"your-credentials"}' > ~/.talky/credentials/google.json
```

**Debug Logging**

Log levels: `DEBUG`, `INFO`, `WARNING`, `ERROR`

Default: `ERROR`

```bash
talky --log-level INFO

# or use environment variable
TALKY_LOG_LEVEL=DEBUG talky  
```
