Local voice mode
Local voice mode keeps voice transcription private and local. Bestie receives an audio attachment from any channel or runtime surface that wires into the voice pipeline, converts it to WAV when needed, runs whisper.cpp, sends only the bounded transcript and metadata to the agent, then deletes raw voice/audio files when configured.
Expected local files
Section titled “Expected local files”.bestie/tools/whisper-bin/whisper-cli.bestie/tools/local-whisper-transcribe.sh.bestie/models/ggml-small.binThe wrapper accepts model path and audio path, converts with ffmpeg, and prints transcript text to stdout.
Automatic setup
Section titled “Automatic setup”If the local files exist, configure shared local voice mode with:
bestie voice setup-localList models and the current configured model:
bestie voice modelsPreview a model download:
bestie voice download-model smallDownload and switch to the model:
bestie voice download-model small --confirm --usebestie voice download-model small --confirm --force --useSupported names are tiny, small, medium, and large-v3-turbo. Existing files are not overwritten unless --force is provided.
ElevenLabs setup
Section titled “ElevenLabs setup”Use ElevenLabs when you want hosted speech-to-text and speech replies instead of local whisper.cpp:
bestie voice setup-elevenlabsbestie doctor --telegram-speech-testSetup asks for an ElevenLabs API key, voice id, TTS model id, STT model id, and output format. Bestie stores the key in .bestie/.env as ELEVENLABS_API_KEY, writes transcription and speech config, and enables Telegram voice/audio attachment transcription plus voice replies for voice inputs. The default speech reply policy is voice-input-only, with an 800-character reply cap and a 30-second cooldown unless existing Telegram config overrides those values.
Voicebox setup
Section titled “Voicebox setup”Bestie also exposes a local Voicebox setup flow:
bestie voice setup-voiceboxRun the command and follow its prompts to configure the local Voicebox integration. Use bestie doctor after setup to check the configured local voice dependencies.
Config preset
Section titled “Config preset”{ "transcription": { "provider": "local-whisper", "command": ".bestie/tools/local-whisper-transcribe.sh", "args": ["{modelPath}", "{audioPath}", "-l", "vi"], "modelPath": ".bestie/models/ggml-small.bin", "timeoutMs": 120000 }, "channels": { "telegram": { "attachments": { "downloadPolicy": "allow", "transcriptionPolicy": "allow", "transcriptionMaxBytes": 10485760, "deleteAfterProcessingKinds": ["voice", "audio"] } } }}For Vietnamese, ggml-small.bin is the practical local baseline. ggml-tiny.bin is faster but commonly too inaccurate for Vietnamese voice chat.
Verify
Section titled “Verify”Run Doctor:
bestie doctorbestie doctor --telegram-speech-testExpected checks include local transcription command, model, ffmpeg, and model quality warnings.
For a real Telegram adapter smoke transcript, run Telegram separately after shared voice is configured:
bestie channels telegram --once --transcript .bestie/logs/telegram-local-voice-smoke.jsonlThe transcript file must not contain raw message text, transcript text, file ids, file paths, owner ids, chat ids, bot tokens, or provider secrets.
Cleanup
Section titled “Cleanup”Preview retained old voice/audio files:
bestie tools attachments cleanup --older-than 7d --kinds voice,audioDelete matched files:
bestie tools attachments cleanup --older-than 7d --kinds voice,audio --confirmVoice is channel-independent
Section titled “Voice is channel-independent”Voice is now a separate capability instead of being coupled to Telegram. A Bestie can use voice features from any supported channel or runtime surface that wires audio input/output into the agent.
This means Telegram can still support voice workflows by passing Telegram voice/audio attachments into the shared pipeline, but Telegram is no longer the owner of the voice feature. Keep voice configuration and voice behavior documented as a standalone capability, then connect it to Telegram, CLI, web, or future adapters as needed.
