mock (desenvolvimento, sem rede), plivo (API de voz + transferência por XML +
reconhecimento de fala GetInput), telnyx (Call Control v2), twilio (Programmable Voice +
Media Streams).
O plugin Voice Call é executado dentro do processo do Gateway. Se você usa um
Gateway remoto, instale e configure o plugin na máquina que executa o
Gateway e reinicie o Gateway para carregá-lo.
Início rápido
1
Instalar o plugin
- Pelo npm
- Por uma pasta local (desenvolvimento)
2
Configurar o provedor e o webhook
Defina a configuração em
plugins.entries.voice-call.config (consulte
Configuração abaixo). No mínimo: provider, as credenciais
do provedor, fromNumber e uma URL de webhook acessível publicamente.3
Verificar a configuração
streaming ou realtime) está ativo.4
Executar um teste de fumaça
--yes para realizar uma breve
chamada de notificação de saída:Configuração
Seenabled: true, mas faltarem credenciais para o provedor selecionado, a
inicialização do Gateway registrará um aviso de configuração incompleta com as chaves ausentes
e não iniciará o runtime. Comandos, chamadas RPC e ferramentas do agente ainda retornarão
a configuração exata ausente quando forem usados.
As credenciais de chamadas de voz aceitam SecretRefs.
plugins.entries.voice-call.config.twilio.authToken, plugins.entries.voice-call.config.realtime.providers.*.apiKey, plugins.entries.voice-call.config.streaming.providers.*.apiKey e plugins.entries.voice-call.config.tts.providers.*.apiKey são resolvidas pela interface padrão de SecretRef; consulte Interface de credenciais SecretRef.Referência de configuração
Chaves de nível superior emplugins.entries.voice-call.config não mostradas acima:
Por padrão, o Twilio usa seu endpoint REST US1. Para processar chamadas em uma
região compatível fora dos EUA, defina
twilio.region como ie1 ou au1 e use credenciais
dessa região. Consulte o
guia da API REST do Twilio para regiões fora dos EUA.
Observações sobre exposição e segurança do provedor
Observações sobre exposição e segurança do provedor
- Twilio, Telnyx e Plivo exigem uma URL de webhook acessível publicamente.
mocké um provedor para desenvolvimento local (sem chamadas de rede).- O Telnyx exige
telnyx.publicKey(ouTELNYX_PUBLIC_KEY), a menos queskipSignatureVerificationseja verdadeiro. skipSignatureVerificationdestina-se somente a testes locais.- No 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é local loopback (agente local do ngrok). Somente para desenvolvimento local.- As URLs do plano gratuito do ngrok podem mudar ou adicionar uma página intermediária; se
publicUrlmudar, as assinaturas do Twilio falharão. Em produção, prefira um domínio estável ou um funnel do Tailscale.
Limites de conexões de streaming
Limites de conexões de streaming
streaming.preStartTimeoutMs(padrão5000) fecha sockets que nunca enviam um quadrostartválido.streaming.maxPendingConnections(padrão32) limita o total de sockets não autenticados antes da inicialização.streaming.maxPendingConnectionsPerIp(padrão4) limita os sockets não autenticados antes da inicialização por IP de origem.streaming.maxConnections(padrão128) limita todos os sockets abertos de fluxo de mídia (pendentes + ativos).
Migrações de configuração legada
Migrações de configuração legada
A análise da configuração normaliza automaticamente estas chaves legadas e registra um
aviso que informa o caminho substituto; a camada de compatibilidade será removida em uma versão
futura (
2026.6.0), portanto execute openclaw doctor --fix para reescrever a configuração
versionada no formato canônico:provider: "log"→provider: "mock"twilio.from→fromNumberstreaming.sttProvider→streaming.providerstreaming.openaiApiKey→streaming.providers.openai.apiKeystreaming.sttModel→streaming.providers.openai.modelstreaming.silenceDurationMs→streaming.providers.openai.silenceDurationMsstreaming.vadThreshold→streaming.providers.openai.vadThresholdrealtime.agentContext.includeSystemPromptfoi removido (o contexto em tempo real agora usa o prompt gerado do agente)
Escopo da sessão
Por padrão, o Voice Call usasessionScope: "per-phone" para que chamadas repetidas do
mesmo chamador mantenham a memória da conversa. Defina sessionScope: "per-call" quando
cada chamada da operadora precisar começar com um contexto novo, por exemplo em fluxos de recepção,
agendamento, IVR ou ponte do Google Meet, nos quais o mesmo número de telefone pode
representar reuniões diferentes.
O Voice Call armazena as chaves de sessão geradas no namespace do agente configurado
(agent:<agentId>:voice:*). Chaves explícitas brutas de integração são resolvidas no
mesmo namespace: uma chave canônica agent:<configuredAgentId>:* mantém esse
proprietário e respeita os aliases session.mainKey/de escopo global do núcleo; entradas
agent:* estrangeiras ou malformadas são delimitadas como uma chave opaca sob o agente
configurado; global e unknown permanecem sentinelas globais.
Conversas de voz em tempo real
realtime seleciona um provedor de voz em tempo real full-duplex para o áudio ao vivo da chamada.
Ele é separado de streaming, que apenas encaminha o áudio para provedores de
transcrição em tempo real.
Comportamento atual do runtime:
realtime.enabledé compatível com Twilio e Telnyx.realtime.provideré opcional. Se não for definido, o Voice Call usará o primeiro provedor de voz em tempo real registrado.- Provedores de voz em tempo real incluídos: Google Gemini Live (
google) e OpenAI (openai), registrados pelos respectivos plugins de provedor. - A configuração bruta pertencente ao provedor fica em
realtime.providers.<providerId>. - Por padrão, o Voice Call disponibiliza a ferramenta compartilhada de tempo real
openclaw_agent_consult. O modelo em tempo real pode chamá-la quando quem liga solicitar raciocínio mais aprofundado, informações atuais ou ferramentas normais do OpenClaw. realtime.consultPolicyadiciona, opcionalmente, orientações sobre quando o modelo em tempo real deve chamaropenclaw_agent_consult.realtime.agentContext.enabledfica desativado por padrão. Quando ativado, o Voice Call injeta uma identidade limitada do agente e uma cápsula com arquivos selecionados do workspace nas instruções do provedor em tempo real durante a configuração da sessão.realtime.fastContext.enabledfica desativado por padrão. Quando ativado, o Voice Call primeiro pesquisa o contexto indexado da memória/sessão para responder à pergunta da consulta e retorna esses trechos ao modelo em tempo real dentro do prazo derealtime.fastContext.timeoutMs; ele só recorre ao agente de consulta completo serealtime.fastContext.fallbackToConsultfortrue.- Se
realtime.providerapontar para um provedor não registrado, ou se nenhum provedor de voz em tempo real estiver registrado, o Voice Call registrará um aviso e ignorará a mídia em tempo real, em vez de causar a falha de todo o plugin. inboundPolicynão pode ser"disabled"quandorealtime.enabledfortrue;validateProviderConfigrejeita essa combinação.- As chaves da sessão de consulta reutilizam a sessão de chamada armazenada quando disponível e, caso contrário, usam o
sessionScopeconfigurado (per-phonepor padrão ouper-callpara chamadas isoladas).
Política de ferramentas
realtime.toolPolicy controla a execução da consulta:
realtime.consultPolicy controla somente as instruções do modelo em tempo real:
Contexto de voz do agente
Ativerealtime.agentContext quando a ponte de voz precisar soar como o agente
OpenClaw configurado sem incorrer em uma viagem completa de ida e volta para
consultar o agente em interações comuns. A cápsula de contexto é adicionada uma
única vez quando a sessão em tempo real é criada, portanto não acrescenta
latência a cada interação. As chamadas a openclaw_agent_consult ainda executam
o agente OpenClaw completo e devem ser usadas para trabalhos com ferramentas,
informações atuais, consultas à memória ou estado do workspace.
Exemplos de provedores em tempo real
- Google Gemini Live
- OpenAI
Padrões: chave de API de
realtime.providers.google.apiKey, GEMINI_API_KEY
ou GOOGLE_API_KEY; modelo gemini-3.1-flash-live-preview;
voz Kore. sessionResumption e contextWindowCompression ficam ativados
por padrão para chamadas mais longas e que podem ser reconectadas. Use
silenceDurationMs, startSensitivity e endSensitivity para ajustar
alternâncias de fala mais rápidas no áudio de telefonia.Transcrição por streaming
streaming seleciona um provedor de transcrição em tempo real para o áudio ao vivo das chamadas.
Comportamento atual em tempo de execução:
streaming.provideré opcional. Se não for definido, o Voice Call usará o primeiro provedor de transcrição em tempo real registrado.- Provedores de transcrição em tempo real incluídos: Deepgram (
deepgram), ElevenLabs (elevenlabs), Mistral (mistral), OpenAI (openai) e xAI (xai), registrados pelos respectivos plugins de provedor. - A configuração bruta pertencente ao provedor fica em
streaming.providers.<providerId>. - Depois que o Twilio envia uma mensagem
startde stream aceita, o Voice Call registra o stream imediatamente, enfileira a mídia recebida por meio do provedor de transcrição enquanto ele se conecta e inicia a saudação inicial somente quando a transcrição em tempo real está pronta. - Se
streaming.providerapontar para um provedor não registrado, ou se nenhum estiver registrado, o Voice Call registrará um aviso e ignorará o streaming de mídia, em vez de causar a falha de todo o plugin.
Exemplos de provedores de streaming
- OpenAI
- xAI
Padrões: chave de API
streaming.providers.openai.apiKey ou
OPENAI_API_KEY; modelo gpt-4o-transcribe; silenceDurationMs: 800;
vadThreshold: 0.5.TTS para chamadas
O Voice Call usa a configuração principalmessages.tts para streaming de fala
nas chamadas. Você pode substituí-la na configuração do plugin usando o
mesmo formato — ela é mesclada profundamente com messages.tts.
- As chaves legadas
tts.<provider>na configuração do plugin (openai,elevenlabs,microsoft,edge) são corrigidas poropenclaw doctor --fix; a configuração persistida deve usartts.providers.<provider>. - O TTS principal é usado quando o streaming de mídia do Twilio está ativado; caso contrário, as chamadas usam como alternativa as vozes nativas do provedor.
- Se um stream de mídia do Twilio já estiver ativo, o Voice Call não usará o
<Say>do TwiML como alternativa. Se o TTS de telefonia não estiver disponível nesse estado, a solicitação de reprodução falhará, em vez de combinar dois caminhos de reprodução. - Quando o TTS de telefonia usa um provedor secundário como alternativa, o Voice Call registra um aviso com a cadeia de provedores (
from,to,attempts) para depuração. - Quando uma interrupção de fala no Twilio ou o encerramento do stream limpa a fila de TTS pendente, as solicitações de reprodução enfileiradas são concluídas, em vez de deixar em espera quem aguarda a conclusão da reprodução.
Exemplos de TTS
- Somente TTS principal
- Substituir pelo ElevenLabs (somente chamadas)
- Substituição do modelo OpenAI (mesclagem profunda)
Chamadas recebidas
Por padrão, a política de chamadas recebidas édisabled. Para ativar chamadas recebidas, defina:
responseModel,
responseSystemPrompt e responseTimeoutMs.
Roteamento por número
Usenumbers quando um plugin de chamadas de voz receber chamadas para vários números
de telefone e cada número precisar se comportar como uma linha diferente. Por exemplo,
um número pode usar um assistente pessoal informal, enquanto outro usa uma persona
empresarial, um agente de resposta diferente e uma voz TTS diferente.
As rotas são selecionadas com base no número To discado fornecido pelo provedor. As chaves devem
ser números E.164. Quando uma chamada chega, o recurso de chamadas de voz resolve uma única vez a
rota correspondente, armazena a rota encontrada no registro da chamada e reutiliza essa
configuração efetiva para a saudação, o fluxo clássico de resposta automática, o fluxo de
consulta em tempo real e a reprodução de TTS. Se nenhuma rota corresponder, será usada a
configuração global de chamadas de voz. Chamadas de saída não usam numbers; informe
explicitamente o destino, a mensagem e a sessão de saída ao iniciar a chamada.
As substituições de rota atualmente permitem:
inboundGreetingttsagentIdresponseModelresponseSystemPromptresponseTimeoutMs
tts é mesclado profundamente sobre a configuração global tts de chamadas de voz, portanto
geralmente é possível substituir apenas a voz do provedor:
Contrato de saída falada
Para respostas automáticas, o recurso de chamadas de voz acrescenta ao prompt do sistema um contrato rigoroso de saída falada que exige uma resposta JSON{"spoken":"..."}. O recurso de chamadas de voz
extrai o texto da fala de forma defensiva:
- Ignora cargas úteis marcadas como conteúdo de raciocínio/erro.
- Analisa JSON direto, JSON em bloco delimitado ou chaves
"spoken"embutidas. - Recua para texto simples e remove parágrafos iniciais que provavelmente contenham planejamento ou metainformações.
Comportamento ao iniciar a conversa
Para chamadasconversation de saída, o tratamento da primeira mensagem é vinculado ao estado de
reprodução em tempo real:
- A limpeza da fila por interrupção da fala e a resposta automática são suprimidas apenas enquanto a saudação inicial está sendo falada.
- Se a reprodução inicial falhar, a chamada retornará a
listeninge a mensagem inicial permanecerá na fila para uma nova tentativa. - A reprodução inicial para streaming do Twilio começa quando o fluxo é conectado, sem atraso adicional.
- A interrupção da fala cancela a reprodução ativa e limpa as entradas TTS do Twilio que estão na fila, mas ainda não começaram a ser reproduzidas. As entradas limpas são resolvidas como ignoradas, permitindo que a lógica da resposta subsequente continue sem aguardar um áudio que nunca será reproduzido.
- Conversas de voz em tempo real usam o próprio turno inicial do fluxo em tempo real. O recurso de chamadas de voz não publica uma atualização TwiML
<Say>legada para essa mensagem inicial, portanto as sessões<Connect><Stream>de saída permanecem conectadas.
Período de tolerância para desconexão do fluxo do Twilio
Quando um fluxo de mídia do Twilio é desconectado, o recurso de chamadas de voz aguarda 2000 ms antes de encerrar automaticamente a chamada:- Se o fluxo se reconectar durante esse período, o encerramento automático será cancelado.
- Se nenhum fluxo for registrado novamente após o período de tolerância, a chamada será encerrada para evitar chamadas ativas travadas.
Coletor de chamadas obsoletas
UsestaleCallReaperSeconds (padrão: 120) para encerrar chamadas que nunca são
atendidas nem chegam a um estado de conversa ativa, por exemplo, chamadas no modo
de notificação para as quais o provedor nunca entrega um Webhook terminal. Defina como 0 para
desativar.
O coletor é executado a cada 30 segundos e encerra apenas chamadas que não têm
um carimbo de data e hora answeredAt e que ainda não estão em um estado terminal ou ativo
(speaking/listening), portanto conversas atendidas nunca são coletadas
por esse temporizador; maxDurationSeconds (padrão: 300) é o limite separado que
encerra chamadas atendidas que duram demais.
Para fluxos no estilo de notificação em que as operadoras podem demorar para entregar Webhooks
de toque/atendimento, aumente staleCallReaperSeconds além do padrão para que chamadas
lentas, porém normais, não sejam coletadas antecipadamente; 120 a 300 segundos é um intervalo
razoável para produção.
Segurança do Webhook
Quando um proxy ou túnel fica à frente do Gateway, o plugin reconstrói a URL pública para verificação da assinatura. Estas opções controlam quais cabeçalhos encaminhados são confiáveis:string[]
Hosts permitidos nos cabeçalhos de encaminhamento.
boolean
Confia em cabeçalhos encaminhados sem uma lista de permissões.
string[]
Confia em cabeçalhos encaminhados apenas quando o IP remoto da solicitação corresponde à lista.
- A proteção contra repetição de Webhooks está habilitada para Twilio, Telnyx e Plivo. Solicitações válidas de Webhook repetidas são confirmadas, mas seus efeitos colaterais são ignorados.
- Os turnos de conversa do Twilio incluem um token por turno nos retornos de chamada de
<Gather>, portanto retornos de chamada de fala obsoletos ou repetidos não podem satisfazer um turno de transcrição pendente mais recente. - Solicitações de Webhook não autenticadas são rejeitadas antes da leitura do corpo quando os cabeçalhos de assinatura exigidos pelo provedor estão ausentes.
- O Webhook de chamadas de voz usa o perfil compartilhado de leitura do corpo antes da autenticação (corpo máximo de 64 KB, tempo limite de leitura de 5 segundos), além de um limite por chave para solicitações em andamento (8 solicitações simultâneas por chave por padrão) antes da verificação da assinatura.
CLI
voicecall
delegam ao runtime de chamadas de voz pertencente ao Gateway, para que a CLI não associe um
segundo servidor de Webhook. Se nenhum Gateway estiver acessível, os comandos recorrerão a
um runtime independente da CLI.
latency lê calls.jsonl no caminho de armazenamento padrão de chamadas de voz. Use
--file <path> para indicar outro registro e --last <n> para limitar
a análise aos últimos N registros (padrão: 200). A saída inclui mínimo/máximo/média,
p50 e p95 para a latência dos turnos e os tempos de espera de escuta.
Ferramenta do agente
Nome da ferramenta:voice_call.
O plugin de chamadas de voz inclui uma Skill de agente correspondente.
RPC do Gateway
dtmfSequence só é válido com mode: "conversation"; chamadas no modo de notificação
devem usar voicecall.dtmf depois que a chamada existir, caso precisem de dígitos
após a conexão.
Solução de problemas
Falha na configuração da exposição do Webhook
Execute a configuração no mesmo ambiente que executa o Gateway:twilio, telnyx e plivo, webhook-exposure deve estar verde. Uma
publicUrl configurada ainda falhará se apontar para um espaço de rede local ou
privado, pois a operadora não consegue retornar chamadas para esses endereços.
Não use localhost, 127.0.0.1, 0.0.0.0, 10.x, 172.16.x-172.31.x,
192.168.x, 169.254.x, fc00::/7, fd00::/8 ou outros intervalos de NAT
de nível de operadora como publicUrl.
Chamadas de saída no modo de notificação do Twilio enviam o TwiML <Say> inicial diretamente
na solicitação de criação da chamada, portanto a primeira mensagem falada não depende de
o Twilio buscar o TwiML do Webhook. Um Webhook público ainda é necessário para retornos de
chamada de status, chamadas de conversa, DTMF antes da conexão, fluxos em tempo real e
controle de chamadas após a conexão.
Use um caminho de exposição pública:
voicecall smoke é uma simulação, a menos que você informe --yes.
Falha nas credenciais do provedor
Verifique o provedor selecionado e os campos de credenciais obrigatórios:- Twilio:
twilio.accountSid,twilio.authTokenefromNumber, ouTWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKENeTWILIO_FROM_NUMBER. - Telnyx:
telnyx.apiKey,telnyx.connectionId,telnyx.publicKeyefromNumber, ouTELNYX_API_KEY,TELNYX_CONNECTION_IDeTELNYX_PUBLIC_KEY. - Plivo:
plivo.authId,plivo.authTokenefromNumber, ouPLIVO_AUTH_IDePLIVO_AUTH_TOKEN.
As chamadas são iniciadas, mas os Webhooks do provedor não chegam
Confirme se o console do provedor aponta para a URL pública exata do Webhook:publicUrlaponta para um caminho diferente deserve.path.- A URL do túnel mudou após o início do Gateway.
- Um proxy encaminha a solicitação, mas remove ou reescreve os cabeçalhos de host/protocolo.
- O firewall ou DNS direciona o nome do host público para outro lugar, em vez do Gateway.
- O Gateway foi reiniciado sem o Plugin de Chamadas de Voz habilitado.
webhookSecurity.allowedHosts como o nome do host público ou use
webhookSecurity.trustedProxyIPs para um endereço de proxy conhecido. Use
webhookSecurity.trustForwardingHeaders somente quando o limite do proxy
estiver sob seu controle.
A verificação da assinatura falha
As assinaturas do provedor são verificadas em relação à URL pública que o OpenClaw reconstrói a partir da solicitação recebida. Se as assinaturas falharem:- Confirme se a URL do Webhook do provedor corresponde exatamente a
publicUrl, incluindo esquema, host e caminho. - Para URLs do plano gratuito do ngrok, atualize
publicUrlquando o nome do host do túnel mudar. - Garanta que o proxy preserve os cabeçalhos originais de host e protocolo ou configure
webhookSecurity.allowedHosts. - Não habilite
skipSignatureVerificationfora de testes locais.
As entradas do Google Meet pelo Twilio falham
O Google Meet usa este Plugin para entradas por discagem pelo Twilio. Primeiro, verifique as Chamadas de Voz:--dtmf-sequence. A chamada telefônica pode estar funcionando
enquanto a reunião rejeita ou ignora uma sequência DTMF incorreta.
O Google Meet inicia o segmento telefônico do Twilio por meio de voicecall.start com uma
sequência DTMF anterior à conexão. As sequências derivadas do PIN incluem o
voiceCall.dtmfDelayMs do Plugin do Google Meet (padrão: 12000 ms) como dígitos
de espera iniciais do Twilio, pois os avisos da discagem do Meet podem chegar com atraso.
As Chamadas de Voz então redirecionam de volta para o processamento em tempo real antes que
a saudação introdutória seja solicitada.
Use openclaw logs --follow para acompanhar as fases em tempo real. Uma entrada bem-sucedida
em uma reunião do Meet pelo Twilio registra esta ordem:
- O Google Meet delega a entrada pelo Twilio às Chamadas de Voz.
- As Chamadas de Voz armazenam o TwiML de DTMF anterior à conexão.
- O TwiML inicial do Twilio é consumido e fornecido antes do processamento em tempo real.
- As Chamadas de Voz fornecem o TwiML em tempo real para a chamada do Twilio.
- O Google Meet solicita a fala introdutória com
voicecall.speakapós o atraso posterior ao DTMF.
openclaw voicecall tail ainda mostra os registros persistidos das chamadas; isso é útil para
o estado e as transcrições das chamadas, mas nem toda transição de Webhook ou em tempo real
aparece ali.
A chamada em tempo real não tem fala
Confirme se apenas um modo de áudio está habilitado:realtime.enabled e
streaming.enabled não podem ser ambos verdadeiros.
Para chamadas em tempo real do Twilio/Telnyx, verifique também:
- Um Plugin de provedor em tempo real está carregado e registrado.
realtime.providernão está definido ou nomeia um provedor registrado.- A chave da API do provedor está disponível para o processo do Gateway.
openclaw logs --followmostra o TwiML em tempo real fornecido, a ponte em tempo real iniciada e a saudação inicial adicionada à fila.