mock (sviluppo, nessuna rete), plivo (Voice API + trasferimento XML +
riconoscimento vocale GetInput), telnyx (Call Control v2), twilio (Programmable Voice +
Media Streams).
Il plugin Voice Call viene eseguito all’interno del processo Gateway. Se utilizzi un
Gateway remoto, installa e configura il plugin sulla macchina che esegue il
Gateway, quindi riavvia il Gateway per caricarlo.
Avvio rapido
1
Install the plugin
- From npm
- From a local folder (dev)
2
Configure provider and webhook
Imposta la configurazione in
plugins.entries.voice-call.config (vedi
Configurazione di seguito). Sono richiesti almeno: provider, le
credenziali del provider, fromNumber e un URL Webhook accessibile pubblicamente.3
Verify setup
streaming o realtime).4
Smoke test
--yes per effettuare una breve
chiamata di notifica in uscita:Configurazione
Seenabled: true ma al provider selezionato mancano le credenziali, all’avvio il Gateway
registra un avviso di configurazione incompleta con le chiavi mancanti e non
avvia il runtime. I comandi, le chiamate RPC e gli strumenti dell’agente restituiscono comunque
l’esatta configurazione mancante quando vengono utilizzati.
Le credenziali delle chiamate vocali accettano SecretRef.
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 vengono risolti tramite l’interfaccia SecretRef standard; consulta Interfaccia delle credenziali SecretRef.Riferimento della configurazione
Chiavi di primo livello inplugins.entries.voice-call.config non mostrate in precedenza:
Twilio utilizza per impostazione predefinita il proprio endpoint REST US1. Per elaborare le chiamate in una
regione non statunitense supportata, imposta
twilio.region su ie1 o au1 e utilizza le credenziali di
quella regione. Consulta la
guida di Twilio all’API REST nelle regioni non statunitensi.
Provider exposure and security notes
Provider exposure and security notes
- Twilio, Telnyx e Plivo richiedono tutti un URL Webhook accessibile pubblicamente.
mockè un provider per lo sviluppo locale (nessuna chiamata di rete).- Telnyx richiede
telnyx.publicKey(oTELNYX_PUBLIC_KEY), a meno cheskipSignatureVerificationnon sia true. skipSignatureVerificationè destinato esclusivamente ai test locali.- Nel piano gratuito di ngrok, imposta
publicUrlsull’URL ngrok esatto; la verifica della firma viene sempre applicata. tunnel.allowNgrokFreeTierLoopbackBypass: trueconsente Webhook Twilio con firme non valide solo quandotunnel.provider="ngrok"eserve.bindè local loopback (agente locale ngrok). Solo per lo sviluppo locale.- Gli URL del piano gratuito di ngrok possono cambiare o aggiungere schermate intermedie; se
publicUrlcambia, le firme Twilio non sono valide. In produzione, preferisci un dominio stabile o un funnel Tailscale.
Streaming connection caps
Streaming connection caps
streaming.preStartTimeoutMs(valore predefinito5000) chiude i socket che non inviano mai un framestartvalido.streaming.maxPendingConnections(valore predefinito32) limita il numero totale di socket non autenticati in attesa dell’avvio.streaming.maxPendingConnectionsPerIp(valore predefinito4) limita i socket non autenticati in attesa dell’avvio per ciascun IP di origine.streaming.maxConnections(valore predefinito128) limita tutti i socket aperti dei flussi multimediali (in attesa + attivi).
Legacy config migrations
Legacy config migrations
L’analisi della configurazione normalizza automaticamente queste chiavi precedenti e registra un
avviso che indica il percorso sostitutivo; il livello di compatibilità verrà rimosso in una versione
futura (
2026.6.0), quindi esegui openclaw doctor --fix per riscrivere la configurazione salvata
nella forma canonica: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.includeSystemPromptviene rimosso (il contesto in tempo reale ora utilizza il prompt dell’agente generato)
Ambito della sessione
Per impostazione predefinita, Voice Call utilizzasessionScope: "per-phone", così le chiamate ripetute dello
stesso chiamante conservano la memoria della conversazione. Imposta sessionScope: "per-call" quando
ogni chiamata dell’operatore deve iniziare con un contesto nuovo, ad esempio per reception,
prenotazioni, IVR o flussi bridge di Google Meet in cui lo stesso numero di telefono può
rappresentare riunioni diverse.
Voice Call archivia le chiavi di sessione generate nello spazio dei nomi dell’agente configurato
(agent:<agentId>:voice:*). Le chiavi di integrazione esplicite non elaborate vengono risolte nello
stesso spazio dei nomi: una chiave canonica agent:<configuredAgentId>:* mantiene tale
proprietario e rispetta gli alias session.mainKey/dell’ambito globale del core; un input
agent:* esterno o non valido viene delimitato come chiave opaca sotto l’agente
configurato; global e unknown rimangono sentinelle globali.
Conversazioni vocali in tempo reale
realtime seleziona un provider vocale in tempo reale full-duplex per l’audio delle chiamate dal vivo.
È separato da streaming, che inoltra l’audio soltanto ai provider di
trascrizione in tempo reale.
Comportamento attuale del runtime:
realtime.enabledè supportato per Twilio e Telnyx.realtime.providerè facoltativo. Se non è impostato, Voice Call usa il primo provider vocale in tempo reale registrato.- Provider vocali in tempo reale inclusi: Google Gemini Live (
google) e OpenAI (openai), registrati dai rispettivi Plugin del provider. - La configurazione non elaborata gestita dal provider si trova in
realtime.providers.<providerId>. - Per impostazione predefinita, Voice Call espone lo strumento in tempo reale condiviso
openclaw_agent_consult. Il modello in tempo reale può chiamarlo quando l’interlocutore richiede un ragionamento più approfondito, informazioni aggiornate o i normali strumenti di OpenClaw. realtime.consultPolicyaggiunge facoltativamente indicazioni sui casi in cui il modello in tempo reale dovrebbe chiamareopenclaw_agent_consult.realtime.agentContext.enabledè disattivato per impostazione predefinita. Quando è abilitato, Voice Call inserisce nelle istruzioni del provider in tempo reale, durante la configurazione della sessione, un’identità delimitata dell’agente e una selezione delimitata di file dell’area di lavoro.realtime.fastContext.enabledè disattivato per impostazione predefinita. Quando è abilitato, Voice Call cerca innanzitutto la domanda della consultazione nel contesto indicizzato della memoria e della sessione e restituisce questi estratti al modello in tempo reale entrorealtime.fastContext.timeoutMs; ricorre all’agente di consultazione completo solo serealtime.fastContext.fallbackToConsultètrue.- Se
realtime.providerfa riferimento a un provider non registrato, oppure non è registrato alcun provider vocale in tempo reale, Voice Call registra un avviso e ignora i contenuti multimediali in tempo reale anziché causare il malfunzionamento dell’intero Plugin. inboundPolicynon deve essere"disabled"quandorealtime.enabledètrue;validateProviderConfigrifiuta questa combinazione.- Quando disponibile, le chiavi della sessione di consultazione riutilizzano la sessione di chiamata archiviata; in caso contrario, usano il valore
sessionScopeconfigurato (per-phoneper impostazione predefinita oppureper-callper chiamate isolate).
Criteri degli strumenti
realtime.toolPolicy controlla l’esecuzione della consultazione:
realtime.consultPolicy controlla esclusivamente le istruzioni del modello in tempo reale:
Contesto vocale dell’agente
Abilitarealtime.agentContext quando il ponte vocale deve esprimersi come
l’agente OpenClaw configurato senza sostenere un ciclo completo di consultazione
dell’agente nelle interazioni ordinarie. La capsula di contesto viene aggiunta
una sola volta alla creazione della sessione in tempo reale, quindi non introduce
latenza per ogni interazione. Le chiamate a openclaw_agent_consult eseguono
comunque l’agente OpenClaw completo e devono essere utilizzate per operazioni
con strumenti, informazioni aggiornate, ricerche nella memoria o stato
dell’area di lavoro.
Esempi di provider in tempo reale
- Google Gemini Live
- OpenAI
Valori predefiniti: chiave API da
realtime.providers.google.apiKey,
GEMINI_API_KEY o GOOGLE_API_KEY; modello
gemini-3.1-flash-live-preview; voce Kore. sessionResumption e
contextWindowCompression sono abilitati per impostazione predefinita
per chiamate più lunghe e riconnettibili. Usa silenceDurationMs,
startSensitivity ed endSensitivity per regolare un’alternanza dei
turni più rapida sull’audio telefonico.Trascrizione in streaming
streaming seleziona un provider di trascrizione in tempo reale per l’audio
delle chiamate dal vivo.
Comportamento attuale in fase di esecuzione:
streaming.providerè facoltativo. Se non è impostato, Voice Call usa il primo provider di trascrizione in tempo reale registrato.- Provider di trascrizione in tempo reale inclusi: Deepgram (
deepgram), ElevenLabs (elevenlabs), Mistral (mistral), OpenAI (openai) e xAI (xai), registrati dai rispettivi Plugin del provider. - La configurazione non elaborata gestita dal provider si trova in
streaming.providers.<providerId>. - Dopo che Twilio invia un messaggio
startdi streaming accettato, Voice Call registra immediatamente lo streaming, accoda i contenuti multimediali in ingresso tramite il provider di trascrizione mentre questo stabilisce la connessione e avvia il saluto iniziale solo quando la trascrizione in tempo reale è pronta. - Se
streaming.providerfa riferimento a un provider non registrato, oppure non ne è registrato alcuno, Voice Call registra un avviso e ignora lo streaming multimediale anziché causare il malfunzionamento dell’intero Plugin.
Esempi di provider di streaming
- OpenAI
- xAI
Valori predefiniti: chiave API
streaming.providers.openai.apiKey o
OPENAI_API_KEY; modello gpt-4o-transcribe; silenceDurationMs: 800;
vadThreshold: 0.5.TTS per le chiamate
Voice Call usa la configurazione principalemessages.tts per la sintesi
vocale in streaming durante le chiamate. Puoi sovrascriverla nella
configurazione del Plugin utilizzando la stessa struttura: viene unita
ricorsivamente a messages.tts.
- Le chiavi legacy
tts.<provider>nella configurazione del Plugin (openai,elevenlabs,microsoft,edge) vengono corrette daopenclaw doctor --fix; la configurazione salvata deve usaretts.providers.<provider>. - Il TTS principale viene usato quando lo streaming multimediale di Twilio è abilitato; altrimenti, le chiamate ricorrono alle voci native del provider.
- Se uno streaming multimediale Twilio è già attivo, Voice Call non ricorre a
<Say>di TwiML. Se il TTS telefonico non è disponibile in tale stato, la richiesta di riproduzione non riesce anziché combinare due percorsi di riproduzione. - Quando il TTS telefonico ricorre a un provider secondario, Voice Call registra un avviso contenente la catena dei provider (
from,to,attempts) per agevolare il debug. - Quando l’interruzione dell’interlocutore o la chiusura dello streaming Twilio svuota la coda TTS in sospeso, le richieste di riproduzione accodate vengono completate anziché lasciare in attesa chi aspetta il completamento della riproduzione.
Esempi di TTS
- Core TTS only
- Override to ElevenLabs (calls only)
- OpenAI model override (deep-merge)
Chiamate in ingresso
Per impostazione predefinita, il criterio per le chiamate in ingresso èdisabled. Per abilitare le chiamate in ingresso, imposta:
responseModel,
responseSystemPrompt e responseTimeoutMs.
Instradamento per numero
Usanumbers quando un singolo plugin Voice Call riceve chiamate per più numeri di
telefono e ciascun numero deve comportarsi come una linea diversa. Ad esempio,
un numero può usare un assistente personale informale, mentre un altro usa un’identità
aziendale, un agente di risposta diverso e una voce TTS diversa.
Le route vengono selezionate in base al numero To chiamato fornito dal provider. Le chiavi devono
essere numeri E.164. Quando arriva una chiamata, Voice Call risolve una sola volta la
route corrispondente, la memorizza nel record della chiamata e riutilizza tale
configurazione effettiva per il saluto, il percorso classico di risposta automatica, il percorso
di consultazione in tempo reale e la riproduzione TTS. Se nessuna route corrisponde, viene usata
la configurazione globale di Voice Call. Le chiamate in uscita non usano numbers; specifica
esplicitamente destinazione, messaggio e sessione in uscita quando avvii la chiamata.
Le sostituzioni specifiche della route attualmente supportano:
inboundGreetingttsagentIdresponseModelresponseSystemPromptresponseTimeoutMs
tts della route viene unito ricorsivamente alla configurazione globale tts di Voice Call, quindi
in genere puoi sostituire solo la voce del provider:
Contratto dell’output vocale
Per le risposte automatiche, Voice Call aggiunge al prompt di sistema un rigido contratto per l’output vocale che richiede una risposta JSON{"spoken":"..."}. Voice Call
estrae in modo difensivo il testo da pronunciare:
- Ignora i payload contrassegnati come contenuto di ragionamento o di errore.
- Analizza JSON diretto, JSON delimitato o chiavi
"spoken"incorporate. - In alternativa usa testo normale e rimuove i probabili paragrafi introduttivi di pianificazione o metacontenuto.
Comportamento all’avvio della conversazione
Per le chiamateconversation in uscita, la gestione del primo messaggio è legata allo stato
di riproduzione in tempo reale:
- La pulizia della coda in caso di interruzione vocale e la risposta automatica vengono soppresse solo mentre il saluto iniziale viene effettivamente pronunciato.
- Se la riproduzione iniziale non riesce, la chiamata torna allo stato
listeninge il messaggio iniziale rimane in coda per un nuovo tentativo. - La riproduzione iniziale per lo streaming Twilio inizia alla connessione del flusso senza ulteriori ritardi.
- L’interruzione vocale interrompe la riproduzione attiva e rimuove le voci TTS Twilio in coda ma non ancora in riproduzione. Le voci rimosse vengono risolte come ignorate, consentendo alla logica delle risposte successive di proseguire senza attendere un audio che non verrà mai riprodotto.
- Le conversazioni vocali in tempo reale usano il turno iniziale del flusso in tempo reale. Voice Call non invia un aggiornamento TwiML
<Say>legacy per quel messaggio iniziale, quindi le sessioni<Connect><Stream>in uscita rimangono collegate.
Periodo di tolleranza per la disconnessione del flusso Twilio
Quando un flusso multimediale Twilio si disconnette, Voice Call attende 2000 ms prima di terminare automaticamente la chiamata:- Se il flusso si riconnette durante tale intervallo, la terminazione automatica viene annullata.
- Se dopo il periodo di tolleranza non viene registrato nuovamente alcun flusso, la chiamata viene terminata per evitare chiamate attive bloccate.
Eliminazione delle chiamate obsolete
UsastaleCallReaperSeconds (valore predefinito 120) per terminare le chiamate che non ricevono mai
risposta e non raggiungono mai uno stato di conversazione attiva, ad esempio le chiamate in modalità
di notifica per le quali il provider non invia mai un Webhook terminale. Impostalo su 0 per
disabilitarlo.
Il processo di eliminazione viene eseguito ogni 30 secondi e termina solo le chiamate prive di
timestamp answeredAt e che non si trovano già in uno stato terminale o attivo
(speaking/listening), quindi le conversazioni a cui è stata data risposta non vengono mai eliminate
da questo timer; maxDurationSeconds (valore predefinito 300) è il limite separato che
termina le chiamate con risposta che durano troppo a lungo.
Per i flussi in stile notifica in cui gli operatori possono impiegare molto tempo a inviare i Webhook
di squillo/risposta, aumenta staleCallReaperSeconds oltre il valore predefinito affinché le chiamate
lente ma normali non vengano eliminate prematuramente; 120-300 secondi è un intervallo ragionevole
per la produzione.
Sicurezza dei Webhook
Quando davanti al Gateway è presente un proxy o un tunnel, il plugin ricostruisce l’URL pubblico per la verifica della firma. Queste opzioni stabiliscono quali intestazioni inoltrate sono considerate attendibili:string[]
Host consentiti provenienti dalle intestazioni di inoltro.
boolean
Considera attendibili le intestazioni inoltrate senza un elenco consentito.
string[]
Considera attendibili le intestazioni inoltrate solo quando l’IP remoto della richiesta corrisponde all’elenco.
- La protezione dalla ripetizione dei Webhook è abilitata per Twilio, Telnyx e Plivo. Le richieste Webhook valide ripetute vengono confermate, ma i relativi effetti collaterali vengono ignorati.
- I turni di conversazione Twilio includono un token specifico per turno nei callback
<Gather>, quindi i callback vocali obsoleti o ripetuti non possono soddisfare un turno di trascrizione in sospeso più recente. - Le richieste Webhook non autenticate vengono rifiutate prima della lettura del corpo quando mancano le intestazioni di firma richieste dal provider.
- Il Webhook voice-call usa il profilo condiviso di lettura del corpo precedente all’autenticazione (corpo massimo di 64 KB, timeout di lettura di 5 secondi) e un limite per chiave delle richieste in corso (8 richieste simultanee per chiave per impostazione predefinita) prima della verifica della firma.
CLI
voicecall
vengono delegati al runtime voice-call gestito dal Gateway, così la CLI non associa un
secondo server Webhook. Se non è possibile raggiungere alcun Gateway, i comandi passano
a un runtime CLI autonomo.
latency legge calls.jsonl dal percorso di archiviazione predefinito di voice-call. Usa
--file <path> per specificare un log diverso e --last <n> per limitare
l’analisi agli ultimi N record (valore predefinito 200). L’output include minimo/massimo/media,
p50 e p95 per la latenza dei turni e i tempi di attesa dell’ascolto.
Strumento dell’agente
Nome dello strumento:voice_call.
Il plugin voice-call include una Skills corrispondente per l’agente.
RPC del Gateway
dtmfSequence è valido solo con mode: "conversation"; le chiamate in modalità notifica
devono usare voicecall.dtmf dopo la creazione della chiamata se necessitano di cifre
successive alla connessione.
Risoluzione dei problemi
La configurazione dell’esposizione del Webhook non riesce
Esegui la configurazione dallo stesso ambiente in cui viene eseguito il Gateway:twilio, telnyx e plivo, webhook-exposure deve essere verde. Anche un
publicUrl configurato non supera il controllo quando punta a uno spazio di rete locale o privato,
perché l’operatore non può richiamare tali indirizzi.
Non usare 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 o altri intervalli NAT
di livello operatore come publicUrl.
Le chiamate in uscita Twilio in modalità notifica inviano il TwiML <Say> iniziale direttamente
nella richiesta di creazione della chiamata, quindi il primo messaggio vocale non dipende dal
recupero del TwiML del Webhook da parte di Twilio. Un Webhook pubblico è comunque necessario per i callback
di stato, le chiamate di conversazione, il DTMF precedente alla connessione, i flussi in tempo reale e
il controllo della chiamata dopo la connessione.
Usa un solo percorso di esposizione pubblica:
voicecall smoke è un’esecuzione di prova, a meno che non specifichi --yes.
Le credenziali del provider non sono valide
Controlla il provider selezionato e i campi delle credenziali obbligatori:- Twilio:
twilio.accountSid,twilio.authTokenefromNumber, oppureTWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKENeTWILIO_FROM_NUMBER. - Telnyx:
telnyx.apiKey,telnyx.connectionId,telnyx.publicKeyefromNumber, oppureTELNYX_API_KEY,TELNYX_CONNECTION_IDeTELNYX_PUBLIC_KEY. - Plivo:
plivo.authId,plivo.authTokenefromNumber, oppurePLIVO_AUTH_IDePLIVO_AUTH_TOKEN.
Le chiamate si avviano, ma i webhook del provider non arrivano
Verifica che la console del provider punti all’URL pubblico esatto del webhook:publicUrlpunta a un percorso diverso daserve.path.- L’URL del tunnel è cambiato dopo l’avvio del Gateway.
- Un proxy inoltra la richiesta, ma rimuove o riscrive le intestazioni host/protocollo.
- Il firewall o il DNS instrada il nome host pubblico verso una destinazione diversa dal Gateway.
- Il Gateway è stato riavviato senza il plugin Voice Call abilitato.
webhookSecurity.allowedHosts sul nome host pubblico oppure utilizza
webhookSecurity.trustedProxyIPs per un indirizzo proxy noto. Utilizza
webhookSecurity.trustForwardingHeaders solo quando il confine del proxy è
sotto il tuo controllo.
La verifica della firma non riesce
Le firme del provider vengono verificate rispetto all’URL pubblico che OpenClaw ricostruisce dalla richiesta in arrivo. Se la verifica delle firme non riesce:- Verifica che l’URL del webhook del provider corrisponda esattamente a
publicUrl, inclusi schema, host e percorso. - Per gli URL del piano gratuito di ngrok, aggiorna
publicUrlquando cambia il nome host del tunnel. - Assicurati che il proxy conservi le intestazioni host e protocollo originali oppure configura
webhookSecurity.allowedHosts. - Non abilitare
skipSignatureVerificational di fuori dei test locali.
Le partecipazioni a Google Meet tramite Twilio non riescono
Google Meet utilizza questo plugin per partecipare tramite chiamata telefonica Twilio. Verifica innanzitutto Voice Call:--dtmf-sequence. La chiamata telefonica può funzionare
correttamente anche se la riunione rifiuta o ignora una sequenza DTMF errata.
Google Meet avvia la tratta telefonica Twilio tramite voicecall.start con una
sequenza DTMF precedente alla connessione. Le sequenze derivate dal PIN includono
voiceCall.dtmfDelayMs del plugin Google Meet (valore predefinito: 12000 ms) come cifre
di attesa Twilio iniziali, poiché i messaggi vocali per l’accesso telefonico a Meet possono arrivare in ritardo. Voice Call quindi
reindirizza nuovamente alla gestione in tempo reale prima che venga richiesto il saluto introduttivo.
Utilizza openclaw logs --follow per la traccia in tempo reale delle fasi. Una corretta partecipazione
a Meet tramite Twilio registra questo ordine:
- Google Meet delega a Voice Call la partecipazione tramite Twilio.
- Voice Call memorizza il TwiML DTMF precedente alla connessione.
- Il TwiML iniziale di Twilio viene elaborato e fornito prima della gestione in tempo reale.
- Voice Call fornisce il TwiML in tempo reale per la chiamata Twilio.
- Google Meet richiede il messaggio vocale introduttivo con
voicecall.speakdopo il ritardo successivo al DTMF.
openclaw voicecall tail mostra comunque i record persistenti delle chiamate; è utile per
lo stato delle chiamate e le trascrizioni, ma non tutte le transizioni dei webhook o in tempo reale
vengono visualizzate in questo comando.
La chiamata in tempo reale non ha audio vocale
Verifica che sia abilitata una sola modalità audio:realtime.enabled e
streaming.enabled non possono essere entrambi impostati su true.
Per le chiamate Twilio/Telnyx in tempo reale, verifica inoltre che:
- Sia caricato e registrato un plugin per un provider in tempo reale.
realtime.providernon sia impostato oppure indichi un provider registrato.- La chiave API del provider sia disponibile per il processo del Gateway.
openclaw logs --followmostri che il TwiML in tempo reale è stato fornito, che il bridge in tempo reale è stato avviato e che il saluto iniziale è stato accodato.