voz-bridge (ElevenLabs). Com ela ligada, o voz-bridge pode ser desligado.
Ligar numa sessão
Rotas
Aceitam a chave de admin ou o token da sessão. As de configuração, só a chave de admin. Sem{sessão} no caminho (POST /api/call), vale ?session=, o campo session do corpo ou a única sessão.
mode: eleven (a IA atende; padrão quando vem agentId, extra ou callId, que é o contrato do voz-bridge) ou browser (um humano fala pelo /call/audio). extra (objeto JSON) vira as variáveis dinâmicas do agente; o agente vem de agentId do pedido, extra.agentId ou agentId da sessão, nessa ordem; só o tenant Glow cai em ELEVENLABS_AGENT_ID.
Agente, chave e eventos por instância
Cada sessão guarda o próprioagentId e eventUrl (https; http só em localhost) na config. A chave da ElevenLabs (elevenKey) e o token dos eventos (eventToken) vão para o cofre do tenant da sessão, cifrados, sob os nomes elevenlabs_api_key e voz_event_token, e valem para todas as sessões do tenant. Eles só entram: nenhuma resposta nem log devolve o valor, o GET mostra só elevenKeySet e eventTokenSet. Precisa de ZAPMEOW_MASTER_KEY (sem cofre o PUT com segredo devolve 503). No painel admin, em Voz e IA, cada sessão do tenant tem um cartão com esses campos (também por PUT /admin/tenants/{id}/s/{sessão}/call/config); o portal do cliente não alcança essa rota.
Sessão sem agente, ou sem chave do próprio tenant, não liga: 422 com sem agente ElevenLabs... ou sem chave ElevenLabs..., antes de discar e sem gastar o teto. Nunca cai na chave de outro tenant. As variáveis ELEVENLABS_API_KEY, ELEVENLABS_AGENT_ID, VOZ_EVENT_URL, VOZ_EVENT_TOKEN e VOZ_TOKEN são só o recuo do tenant Glow (a chave e o token gravados no cofre dele vencem o env).
Códigos
Controles
- Teto diário (
dailyCap, padrão 20 ouZAPMEOW_VOICE_TETO): contado no Postgres (zm_voice_usage), atômico, vira à meia-noite do fuso da sessão.409e422não gastam o teto.0bloqueia tudo. - Janela (
windowStart/windowEnd, padrão 08:00 às 21:00 emAmerica/Sao_Paulo): fora dela,403. Os dois vazios = sem janela. Início maior que o fim vale pela madrugada. - Lista de teste (
allowed): vazia = qualquer número; com números, só eles. - Uma chamada por vez por sessão; teto de 15 minutos e 90 s sem resposta.
Aviso de andamento ao Convex
ComeventUrl na config da sessão (ou VOZ_EVENT_URL, só no tenant Glow) e callId no pedido, o ZapMeow avisa o Convex como o voz-bridge: POST com Authorization: Bearer <eventToken do cofre do tenant> (no tenant Glow, o recuo é $VOZ_EVENT_TOKEN ou $VOZ_TOKEN; sem token, sem o cabeçalho) e corpo {callId, event, error}. Eventos: ringing, answered, ended, rejected, no_answer, cada final uma vez só. A IA entra no aceite do par, sem esperar o primeiro pacote de áudio.
Para o Convex trocar o voz-bridge pelo ZapMeow, basta apontar VOZ_BRIDGE_URL para https://<zapmeow>/api/<sessão> e VOZ_BRIDGE_TOKEN (é o nome que o Convex lê) para o token da sessão. scripts/trocar-voz-convex.sh faz a troca e a reversão.
Áudio do lead e latência
A voz do lead passa pelo RNNoise (rede neural, cgo) antes de ir ao agente: ruído de fundo não vira interrupção.VOZ_NOISE_GATE=0 desliga e manda o áudio cru. A latência (fim da fala do lead até o 1º áudio da IA na chamada) sai no log (latência: N ms) e em call/status (chamada.latencia: amostras, mediaMs, minMs, maxMs, ultimasMs). Para comparar com o voz-bridge na mesma chamada, use scripts/ab-latencia.mts.
Variáveis
O agente da ElevenLabs precisa estar configurado com áudio
pcm_16000 na entrada e na saída.