kesha-voice-kit
by drakulavich
README.md
<p align="center">
<img src="https://github.com/drakulavich/kesha-voice-kit/raw/main/docs/assets/logo.png" alt="Kesha Voice Kit" width="200">
</p>
<h1 align="center">Kesha Voice Kit</h1>
<p align="center">
<a href="https://flakiness.io/Laputa/kesha-voice-kit"><img src="https://img.shields.io/endpoint?url=https%3A%2F%2Fflakiness.io%2Fapi%2Fbadge%3Finput%3D%257B%2522badgeToken%2522%253A%2522badge-2IKMRRqUxh9P3w8Ym3Szf0%2522%257D" alt="Tests"></a>
<a href="https://www.npmjs.com/package/@drakulavich/kesha-voice-kit"><img src="https://img.shields.io/npm/v/@drakulavich/kesha-voice-kit" alt="npm version"></a>
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
<a href="https://bun.sh"><img src="https://img.shields.io/badge/runtime-Bun-f9f1e1?logo=bun" alt="Bun"></a>
</p>
<p align="center"><b>Kesha listens and talks back.</b><br>Your agent gets a voice message, Kesha turns it into text on your machine, and speaks the reply once you add <code>kesha install --tts</code> (<a href="docs/use-cases.md#sending-voice-replies">voice replies</a>). Fastest on Apple Silicon with CoreML, and it runs on Linux and Windows through ONNX.</p>
- **Transcribe locally** — [25 languages](docs/languages.md#speech-to-text-25), up to ~19x faster than Whisper on Apple Silicon, ~10x on an x86 CPU
- **Speak back** — text-to-speech in [9 languages](docs/languages.md#text-to-speech)
- **Plug into agents** — ship voice workflows as CLI commands, an MCP server, an <a href="docs/openclaw.md">OpenClaw</a> skill, or a <a href="docs/hermes.md">Hermes</a> agent
- **Small Rust engine** — single ~74 MB binary, no ffmpeg, no Python, no native Node addons
<p align="center">
<img src="https://github.com/drakulavich/kesha-voice-kit/raw/main/docs/assets/demo.webp" alt="kesha demo: an English voice message transcribed, a Russian one as JSON with automatic language detection, then text-to-speech into a wav" width="800">
</p>
## Quick start
Runtime: **[Bun](https://bun.sh)** >= 1.4.0.
```bash
# 1. Install Bun (skip if you have it)
curl -fsSL https://bun.sh/install | bash # macOS/Linux — or: brew install bun
powershell -c "irm bun.sh/install.ps1 | iex" # Windows
# 2. Install Kesha
bun add -g @drakulavich/kesha-voice-kit
kesha --version # confirms `kesha` resolved on PATH
# 3. Download the engine and models — pick one path
kesha init # guided: TTS languages and optional VAD / diarization
kesha install --plan && kesha install # manual: preview the sizes, then download
# 4. Transcribe
kesha audio.ogg # transcript to stdout
```
`kesha install` pulls ~2.5 GB on Linux/Windows and ~0.6 GB on Apple Silicon, whose CoreML engine reads a smaller model set. It is always explicit — nothing downloads behind your back — and reports download progress on stderr. If `bun --version` fails right after step 1, reload your PATH: `exec $SHELL -l`.
Prefer Homebrew or Docker? See [Other install methods](#other-install-methods).
Air-gapped or behind a corporate mirror? See [docs/model-mirror.md](docs/model-mirror.md).
### Platform support
All three targets transcribe, detect the spoken language, run VAD, and speak. The macOS-only rows need Apple frameworks — they are not a missing port. Windows is a tested path rather than a published binary nobody ran: CI does a cold `kesha install` on `windows-latest`, transcribes a fixture, and round-trips a synthesis ([#216](https://github.com/drakulavich/kesha-voice-kit/issues/216), [#667](https://github.com/drakulavich/kesha-voice-kit/pull/667)).
| | macOS arm64 | Linux x64 | Windows x64 |
|---|:---:|:---:|:---:|
| Transcribe · audio language ID · [VAD](docs/vad.md) | CoreML / ANE | ONNX CPU | ONNX CPU |
| TTS — `en` `ru` `es` `fr` `it` `pt` | ✅ | ✅ | ✅ |
| TTS — `hi` `ja` `zh` and macOS system voices | ✅ | — | — |
| Mic capture and live dictation (`kesha record`) | ✅ | — | — |
| Speaker diarization (`--speakers`) | ✅ | — | — |
| Word-level timestamps (`words` in `--json`) | ✅ | ✅ | ✅ |
| Voice auto-routing from the text's language | ✅ | pass `--lang` | pass `--lang` |
Intel Macs get no published engine binary. Full matrix with maturity labels: [docs/product-positioning.md](docs/product-positioning.md#platform-matrix).
## Plug into your agent
- **MCP server** — `kesha mcp` exposes transcribe/synthesize/list tools to any MCP client (Claude, Cursor, Codex, Gemini). Setup: [docs/mcp.md](docs/mcp.md).
- **OpenClaw** — give your LLM agent ears. Install & config: [docs/openclaw.md](docs/openclaw.md).
- **Hermes Agent** — local STT/TTS through Hermes command providers. Setup: [docs/hermes.md](docs/hermes.md).
- **Raycast** (macOS) — offline microphone dictation from the launcher: *Dictate to Clipboard* records with a live signal meter, auto-stops on silence, transcribes locally, and copies the text. [Install from the Raycast Store](https://www.raycast.com/drakulavich/kesha-voice-kit) · source: [`raycast/`](raycast/).
- **Programmatic API** — `@drakulavich/kesha-voice-kit/core` for use inside a Bun program. See [docs/api.md](docs/api.md).
## Speech-to-text
```bash
kesha audio.ogg # transcribe (plain text)
kesha --format transcript audio.ogg # text + language/confidence
kesha --format json audio.ogg # full JSON with lang fields
kesha --json --timestamps audio.ogg # JSON with timestamped segments
kesha --itn audio.ogg # spelled-out numbers -> digits
kesha --toon audio.ogg # compact LLM-friendly TOON
```
Multiple files get `head`-style headers; stdout is the transcript, stderr is errors — pipe-friendly:
```bash
$ kesha freedom.ogg tahiti.ogg
=== freedom.ogg ===
Свободу попугаям! Свободу!
=== tahiti.ogg ===
Таити, Таити! Не были мы ни в какой Таити! Нас и тут неплохо кормят.
```
- **Record from the mic (macOS):** `kesha record --out hello.wav`, then `kesha hello.wav`. Linux and Windows do not capture the microphone; pass an existing audio file instead. See [docs/stt.md](docs/stt.md#recording-from-the-microphone-macos).
- **Live dictation (darwin-arm64):** `kesha record --live | pbcopy` prints the transcript as you speak; `--auto-stop` ends it after silence once VAD is installed. Ctrl-C still prints what you dictated. See [docs/stt.md](docs/stt.md#live-dictation-darwin-arm64).
- **Long / silence-heavy audio:** install VAD (`kesha install --vad`); Kesha auto-uses it past 120 s. Without VAD, long audio falls back to fixed ASR chunks. See [docs/vad.md](docs/vad.md).
- **Speaker diarization (darwin-arm64):** `kesha install --diarize`, then `kesha --json --speakers meeting.m4a` stamps each segment with a `speaker` id. See [docs/stt.md](docs/stt.md#speaker-diarization-darwin-arm64).
- **Word-level timestamps (every platform):** `kesha --json --timestamps audio.ogg` adds a `words` array to each segment. See [docs/stt.md](docs/stt.md#word-level-timestamps-every-platform).
- **Text-language detection:** JSON and TOON results include `textLanguage`, separate from the spoken `audioLanguage`. See [docs/stt.md](docs/stt.md#text-language-detection).
- **Written-form numbers:** `--itn` turns spelled-out English numbers into digits (`"two hundred thirty two"` → `"232"`). See [docs/stt.md](docs/stt.md#written-form-numbers---itn).
- **A file name starting with `-`:** write it as `./-file.wav`. See [docs/stt.md](docs/stt.md#a-file-name-starting-with--).
## Text-to-speech
Kesha speaks back in [9 languages](docs/languages.md#text-to-speech). Kokoro runs natively through FluidAudio CoreML/ANE on Apple Silicon and through ONNX on Linux and Windows; Russian uses Vosk-TTS, while `macos-*` system voices need no model download. On macOS Kesha picks the voice from the text's own language; on Linux and Windows, state the language with `--lang <code>` (or the voice with `--voice <id>`) — otherwise the engine default speaks.
```bash
kesha install --tts # English voices; sizes differ per platform — preview: kesha install --plan
kesha install --tts en ru # + Russian (+~937 MB, Vosk)
kesha say "Hello, world" > hello.wav
kesha say "Привет, мир" > privet.wav # auto-routes by language (macOS)
kesha say --lang ru "Привет, мир" > privet.wav # explicit — the Linux/Windows path
kesha say --voice ru-vosk-m02 "Голос в текст." > ru.wav
```
**Output formats** (`--format`, or inferred from the `--out` extension):
```bash
kesha say "Hello" --out hi.wav # WAV (default, uncompressed)
kesha say "Hello" --format ogg-opus --out hi.ogg # OGG/Opus — messenger voice notes
kesha say "Hello" --format flac --out hi.flac # FLAC — lossless, plays in every browser incl. Safari/iOS
```
`kesha say --list-voices` lists the voices kesha knows; some need `kesha install --tts <lang>` before they speak. Voices, the full catalogue, macOS system voices, SSML, speaking rate (`--rate`, `<prosody>`), Russian word stress, and Russian/English abbreviation handling are all in **[docs/tts.md](docs/tts.md)**.
## Languages
**Speech-to-text** spans 25 languages and **text-to-speech** 9 — full tables with codes, flags, and per-platform availability in **[docs/languages.md](docs/languages.md)**. Audio language detection identifies [107 languages](https://huggingface.co/speechbrain/lang-id-voxlingua107-ecapa).
## Performance
> **Up to ~19x faster than Whisper** on Apple Silicon (M2), **~10x faster** on an x86 Linux CPU (~2.5x faster than faster-whisper)
Compared against Whisper `large-v3-turbo`, all engines auto-detecting language:

Full per-file breakdown (Russian + English): [BENCHMARK.md](BENCHMARK.md). The chart is from an M2. The x86 figure comes from a GitHub-hosted `ubuntu-latest` runner (AMD EPYC, ONNX on CPU), where openai-whisper runs in FP32.
## Other install methods
Except Nix, these install the Bun CLI wrapper; engine + models still download explicitly via `kesha install`.
- **Homebrew** — `brew install drakulavich/tap/kesha-voice-kit` · [docs/distribution.md](docs/distribution.md#homebrew)
- **Linux packages** (`.deb`/`.rpm`, x64) — published on stable releases, see [docs/distribution.md](docs/distribution.md#linux-packages)
- **Docker** (GHCR image) — [docs/docker.md](docs/docker.md)
- **Nix** (`aarch64-darwin` / `x86_64-linux`) — builds the engine from source (`nix build github:drakulavich/kesha-voice-kit#kesha-engine`). The full `kesha` CLI via `nix run` / `nix profile install` is **not yet available** — it needs a maintainer with Nix to populate a build hash ([#946](https://github.com/drakulavich/kesha-voice-kit/issues/946)). · [docs/distribution.md](docs/distribution.md#nix)
- **Shell completions + manpage** — `kesha completions bash|zsh|fish` and `kesha manpage` print the packaged files to install wherever your shell expects them.
## More
- [Architecture](docs/architecture.md) — runtime data flow, the models that ship, the CLI ↔ Rust engine boundary, model pinning, and where tests live.
- [Use cases](docs/use-cases.md) — copy-paste recipes (transcribe a meeting, speak from OpenClaw, run offline, move the cache).
- [Product positioning](docs/product-positioning.md) — supported workflows, non-goals, maturity labels, platform matrix.
- [Changelog](CHANGELOG.md) — every release, with the behaviour changes spelled out.
- **Diagnostics:** `kesha status` (`--disk` for cache usage, `--json` for scripts, `--check` exits 1 unless the engine and ASR model are installed), `kesha doctor`, `kesha support-bundle` (redacted `.tar.gz` for issues), and `kesha logs` produce local, content-free diagnostics — see [docs/diagnostic-logs.md](docs/diagnostic-logs.md). Every failure prints a stable `error [CODE]: …` line and a documented [process exit code](docs/errors.md#process-exit-codes).
- **Moving the files:** one variable, `KESHA_HOME`, moves everything Kesha writes (models, logs, stats) into a directory of your choice — see [where Kesha keeps its files](docs/diagnostic-logs.md#where-kesha-keeps-its-files).
- **Scripting & CI:** `--json` (or `--toon`) for machine-readable output (each file's `warnings` repeats what stderr warned about it), `--include-errors` (with either) to get per-file failures on stdout alongside the results, `--quiet`/`-q` to silence progress, and `--no-color` (or `NO_COLOR=1`) for plain logs. Colors switch off automatically when `CI=true`.
- **Privacy / Local Stats:** Stats are **off by default** and fully local. Opt in with `kesha stats enable` to record content-free operational metrics in a local SQLite database — never networked, never storing audio, transcripts, text, or paths. Full commands & lifecycle: [docs/local-stats.md](docs/local-stats.md).
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) and the [Decision log](docs/decision-log.md) (why platform/model choices were made — and reversed). Dev setup: `just dev-setup` (Bun, Rust, nextest, platform libs).
## License
Made with 💛🩵 and 🥤 energy under MIT License
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessResponsive