Voice Call (plugin)
Chamadas de voz para o OpenClaw por meio de um plugin. Oferece suporte a notificações de saída e conversas de múltiplos turnos com políticas de entrada. Provedores atuais:twilio(Programmable Voice + Media Streams)telnyx(Call Control v2)plivo(Voice API + transferência XML + reconhecimento de fala GetInput)mock(desenvolvimento/sem rede)
- Instale o plugin
- Reinicie o Gateway
- Configure em
plugins.entries.voice-call.config - Use
openclaw voicecall ...ou a ferramentavoice_call
Onde ele é executado (local vs remoto)
O plugin Voice Call é executado dentro do processo do Gateway. Se você usa um Gateway remoto, instale/configure o plugin na máquina que executa o Gateway e depois reinicie o Gateway para carregá-lo.Instalação
Opção A: instalar pelo npm (recomendado)
Opção B: instalar a partir de uma pasta local (desenvolvimento, sem cópia)
Configuração
Defina a config emplugins.entries.voice-call.config:
- Twilio/Telnyx exigem uma URL de webhook acessível publicamente.
- Plivo exige uma URL de webhook acessível publicamente.
mocké um provedor local para desenvolvimento (sem chamadas de rede).- Se configs antigas ainda usam
provider: "log",twilio.fromou chaves OpenAI legadas destreaming.*, executeopenclaw doctor --fixpara reescrevê-las. - Telnyx exige
telnyx.publicKey(ouTELNYX_PUBLIC_KEY) a menos queskipSignatureVerificationseja true. skipSignatureVerificationé apenas para testes locais.- Se você usar o plano gratuito do ngrok, defina
publicUrlcom a URL exata do ngrok; a verificação de assinatura é sempre aplicada. tunnel.allowNgrokFreeTierLoopbackBypass: truepermite webhooks do Twilio com assinaturas inválidas somente quandotunnel.provider="ngrok"eserve.bindé loopback (agente local do ngrok). Use apenas para desenvolvimento local.- URLs do plano gratuito do ngrok podem mudar ou adicionar comportamento intersticial; se
publicUrlmudar, as assinaturas do Twilio falharão. Para produção, prefira um domínio estável ou Tailscale funnel. - Padrões de segurança do streaming:
streaming.preStartTimeoutMsfecha sockets que nunca enviam um framestartválido.
streaming.maxPendingConnectionslimita o total de sockets pré-início não autenticados.streaming.maxPendingConnectionsPerIplimita os sockets pré-início não autenticados por IP de origem.streaming.maxConnectionslimita o total de sockets abertos de fluxo de mídia (pendentes + ativos).- O fallback de runtime ainda aceita essas chaves antigas de voice-call por enquanto, mas o caminho de regravação é
openclaw doctor --fixe o shim de compatibilidade é temporário.
Transcrição por streaming
streaming seleciona um provedor de transcrição em tempo real para áudio de chamada ao vivo.
Comportamento atual do runtime:
streaming.provideré opcional. Quando não definido, o Voice Call usa o primeiro provedor de transcrição em tempo real registrado.- Hoje, o provedor empacotado é o OpenAI, registrado pelo plugin empacotado
openai. - A config bruta pertencente ao provedor fica em
streaming.providers.<providerId>. - Se
streaming.providerapontar para um provedor não registrado, ou se nenhum provedor de transcrição em tempo real estiver registrado, o Voice Call registra um aviso e ignora o streaming de mídia em vez de falhar o plugin inteiro.
- Chave de API:
streaming.providers.openai.apiKeyouOPENAI_API_KEY - model:
gpt-4o-transcribe silenceDurationMs:800vadThreshold:0.5
openclaw doctor --fix:
streaming.sttProvider→streaming.providerstreaming.openaiApiKey→streaming.providers.openai.apiKeystreaming.sttModel→streaming.providers.openai.modelstreaming.silenceDurationMs→streaming.providers.openai.silenceDurationMsstreaming.vadThreshold→streaming.providers.openai.vadThreshold
Limpador de chamadas obsoletas
UsestaleCallReaperSeconds para encerrar chamadas que nunca recebem um webhook terminal
(por exemplo, chamadas em modo notify que nunca são concluídas). O padrão é 0
(desativado).
Faixas recomendadas:
- Produção:
120–300segundos para fluxos no estilo notify. - Mantenha esse valor maior que
maxDurationSecondspara que chamadas normais possam terminar. Um bom ponto de partida émaxDurationSeconds + 30–60segundos.
Segurança de webhook
Quando um proxy ou túnel fica na frente do Gateway, o plugin reconstrói a URL pública para verificação de assinatura. Essas opções controlam em quais headers encaminhados confiar.webhookSecurity.allowedHosts cria uma allowlist de hosts a partir de headers de encaminhamento.
webhookSecurity.trustForwardingHeaders confia em headers encaminhados sem uma allowlist.
webhookSecurity.trustedProxyIPs só confia em headers encaminhados quando o IP remoto
da solicitação corresponde à lista.
A proteção contra replay de webhook está ativada para Twilio e Plivo. Solicitações de webhook
repetidas e válidas são reconhecidas, mas ignoradas quanto a efeitos colaterais.
Os turnos de conversa do Twilio incluem um token por turno nos callbacks <Gather>, para que
callbacks de fala obsoletos/repetidos não possam satisfazer um turno de transcrição pendente mais novo.
Solicitações de webhook não autenticadas são rejeitadas antes da leitura do corpo quando
faltam os headers de assinatura exigidos pelo provedor.
O webhook de voice-call usa o perfil compartilhado de corpo pré-auth (64 KB / 5 segundos)
mais um limite por IP de solicitações em andamento antes da verificação de assinatura.
Exemplo com um host público estável:
TTS para chamadas
O Voice Call usa a configuração principalmessages.tts para
fala por streaming nas chamadas. Você pode substituí-la na config do plugin com o
mesmo formato — ela é mesclada profundamente com messages.tts.
- Chaves legadas
tts.<provider>dentro da config do plugin (openai,elevenlabs,microsoft,edge) são migradas automaticamente paratts.providers.<provider>no carregamento. Prefira o formatoprovidersna config versionada. - A fala da Microsoft é ignorada para chamadas de voz (o áudio de telefonia precisa de PCM; o transporte atual da Microsoft não expõe saída PCM de telefonia).
- O TTS principal é usado quando o streaming de mídia do Twilio está ativado; caso contrário, as chamadas recorrem às vozes nativas do provedor.
- Se um stream de mídia do Twilio já estiver ativo, o Voice Call não recorre a
<Say>do TwiML. Se o TTS de telefonia não estiver disponível nesse estado, a solicitação de reprodução falhará em vez de misturar dois caminhos de reprodução. - Quando o TTS de telefonia recorre a um provedor secundário, o Voice Call registra um aviso com a cadeia de provedores (
from,to,attempts) para depuração.
Mais exemplos
Use apenas o TTS principal (sem substituição):Chamadas de entrada
A política de entrada tem o padrãodisabled. Para ativar chamadas de entrada, defina:
inboundPolicy: "allowlist" é uma filtragem de ID do chamador de baixa garantia. O plugin
normaliza o valor From fornecido pelo provedor e o compara com allowFrom.
A verificação de webhook autentica a entrega do provedor e a integridade do payload, mas
não prova a posse do número do chamador PSTN/VoIP. Trate allowFrom como
filtragem de ID do chamador, não como identidade forte do chamador.
As respostas automáticas usam o sistema de agent. Ajuste com:
responseModelresponseSystemPromptresponseTimeoutMs
Contrato de saída falada
Para respostas automáticas, o Voice Call acrescenta um contrato estrito de saída falada ao prompt do sistema:{"spoken":"..."}
- Ignora payloads marcados como conteúdo de raciocínio/erro.
- Faz parsing de JSON direto, JSON delimitado por cercas ou chaves
"spoken"inline. - Recorre a texto simples e remove parágrafos iniciais que provavelmente sejam de planejamento/meta.
Comportamento de inicialização da conversa
Para chamadasconversation de saída, o tratamento da primeira mensagem está vinculado ao estado de reprodução ao vivo:
- A limpeza da fila por barge-in e a resposta automática são suprimidas apenas enquanto a saudação inicial estiver sendo falada ativamente.
- Se a reprodução inicial falhar, a chamada volta para
listeninge a mensagem inicial permanece na fila para nova tentativa. - A reprodução inicial para streaming do Twilio começa na conexão do stream sem atraso extra.
Tolerância para desconexão de stream do Twilio
Quando um stream de mídia do Twilio é desconectado, o Voice Call espera2000ms antes de encerrar automaticamente a chamada:
- Se o stream se reconectar durante essa janela, o encerramento automático é cancelado.
- Se nenhum stream for registrado novamente após o período de tolerância, a chamada será encerrada para evitar chamadas ativas travadas.
CLI
latency lê calls.jsonl do caminho de armazenamento padrão de voice-call. Use
--file <path> para apontar para um log diferente e --last <n> para limitar a análise
aos últimos N registros (padrão 200). A saída inclui p50/p90/p99 para
latência por turno e tempos de espera de escuta.
Ferramenta do agent
Nome da ferramenta:voice_call
Ações:
initiate_call(message, to?, mode?)continue_call(callId, message)speak_to_user(callId, message)end_call(callId)get_status(callId)
skills/voice-call/SKILL.md.
RPC do Gateway
voicecall.initiate(to?,message,mode?)voicecall.continue(callId,message)voicecall.speak(callId,message)voicecall.end(callId)voicecall.status(callId)