Pular para o conteúdo principal
O ChatCLI sintetiza fala via o pacote llm/tts (espelha o llm/transcription): o tool @speak gera um arquivo de áudio, e o gateway pode responder em voz. Local/keyless-first, e não preso a um provedor — incluindo um motor embarcado (Kokoro via sherpa-onnx) que roda offline em Linux, macOS e Windows sem chave de API.

Seleção de backend (local primeiro)

tts.NewFromEnv escolhe nesta ordem, degradando para null (desativado) quando nada está configurado:
  1. CHATCLI_TTS_CMD → comando local (template com {text} e {output}). Keyless.
  2. CHATCLI_TTS_URL → endpoint OpenAI-compatível (/audio/speech), keyless salvo CHATCLI_TTS_KEY.
  3. Motor embarcado (Kokoro) — usado automaticamente quando o cache já está provisionado; o modo auto nunca dispara o download sozinho (fixe CHATCLI_TTS_PROVIDER=embedded para provisionar).
  4. CLI local no PATH: macOS say, espeak-ng, espeak — uso automático sem config.
  5. OPENAI_API_KEY → OpenAI TTS.
  6. GROQ_API_KEY → Groq TTS (mesmo shape OpenAI).
  7. GOOGLEAI_API_KEY/GEMINI_API_KEYGemini TTS nativo (retorna PCM, embrulhado em WAV).
CHATCLI_TTS_PROVIDER fixa um backend (embedded/kokoro | command | url | openai | groq | google). CHATCLI_TTS_VOICE e CHATCLI_TTS_MODEL ajustam voz/modelo.
Multi-provedor de verdade: qualquer servidor que fale /audio/speech entra só apontando CHATCLI_TTS_URL. Anthropic e a maioria dos 14 provedores de chat não expõem API de voz — por isso não dá para “estender a todos”: o endpoint não existe.

Motor embarcado (Kokoro) — voz neural offline, sem chave

export CHATCLI_TTS_PROVIDER=embedded
Na primeira síntese, o ChatCLI baixa para o cache do usuário (uma única vez, ~150 MB):
  • o CLI sherpa-onnx-offline-tts pré-compilado para a sua plataforma (~25 MB, build shared), e
  • o modelo kokoro-int8-multi-lang-v1_0 (~126 MB) — 53 vozes neurais em inglês, português brasileiro, espanhol, francês, hindi, italiano, japonês e mandarim.
Sem cgo, sem servidor, sem API key: o binário de release do ChatCLI permanece intocado; a síntese roda em um processo filho por clipe. Plataformas suportadas: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64.

Roteamento de voz por idioma

Cada resposta é roteada para a voz do idioma detectado — uma conversa mista pt/en responde cada mensagem com a voz e o sotaque certos:
VariávelFunçãoPadrão
CHATCLI_TTS_VOICEVoz para respostas em inglês (e default geral)bm_george (britânico)
CHATCLI_TTS_VOICE_PTVoz para respostas em portuguêspm_alex (pt-BR)
Outras vozes notáveis: bm_daniel, bm_fable, bm_lewis (britânicas), pm_santa, pf_dora (pt-BR), af_*/am_* (americanas). Uma voz explícita passada ao @speak sempre vence o roteamento.

Provisionamento — atômico e auditável

  • Download .part → extração em .tmprename atômico → marcador versionado escrito por último: uma queda no meio nunca deixa um cache “meio pronto” passando por instalado.
  • A extração do tar é confinada (sem path traversal, sem symlink escapante, com teto anti tar-bomb) e a varredura do cache roda dentro de um os.Root (confinamento de kernel).
  • CHATCLI_TTS_CACHE_DIR realoca o cache (precisa ser caminho absoluto) — útil para caches compartilhados e pré-seeding em ambientes air-gapped.
Com ffmpeg no PATH, os clipes saem em OGG/Opus (voice note nativa no Telegram). Sem ffmpeg, degrada para WAV — a resposta nunca se perde.

Tool @speak

<tool_call name="@speak" args='{"cmd":"say","args":{"text":"Build finalizado","format":"mp3"}}' />
<tool_call name="@speak" args='{"cmd":"status"}' />
SubcomandoFunção
say {text, voice?, format?, out?}sintetiza para um arquivo (formatos: mp3/wav/opus/ogg/aac/flac); out opcional
statusmostra o backend efetivo

Resposta em voz pelo gateway

O gateway responde voz com voz por padrão (CHATCLI_GATEWAY_VOICE_REPLY=auto): mandou áudio, volta áudio; mandou texto, volta texto. O usuário também liga/desliga pedindo na própria conversa (“responde em áudio” / “para de mandar áudio”) via tool @voice. A página Respostas em Voz no Gateway cobre tudo: os modos auto|always|never, o toggle por conversa, a escrita speech-aware (sem emoji/markdown no áudio) e o transcode para voice note. Veja o estado em /config (Integrações · Gateway · Resposta em voz (TTS)).

Relacionado