Voice Call (plugin)
Les appels vocaux pour OpenClaw via un plugin. Prend en charge les notifications sortantes et les conversations à plusieurs tours avec des politiques d’appels entrants. Fournisseurs actuels :twilio(Programmable Voice + Media Streams)telnyx(Call Control v2)plivo(Voice API + transfert XML + parole GetInput)mock(dev/sans réseau)
- Installez le plugin
- Redémarrez la Gateway
- Configurez sous
plugins.entries.voice-call.config - Utilisez
openclaw voicecall ...ou l’outilvoice_call
Où il s’exécute (local vs distant)
Le plugin Voice Call s’exécute dans le processus Gateway. Si vous utilisez une Gateway distante, installez/configurez le plugin sur la machine qui exécute la Gateway, puis redémarrez la Gateway pour le charger.Installation
Option A : installer depuis npm (recommandé)
Option B : installer depuis un dossier local (dev, sans copie)
Configuration
Définissez la configuration sousplugins.entries.voice-call.config :
- Twilio/Telnyx exigent une URL de webhook publiquement joignable.
- Plivo exige une URL de webhook publiquement joignable.
mockest un fournisseur de développement local (sans appels réseau).- Si des configurations plus anciennes utilisent encore
provider: "log",twilio.fromou les anciennes clés OpenAIstreaming.*, exécutezopenclaw doctor --fixpour les réécrire. - Telnyx exige
telnyx.publicKey(ouTELNYX_PUBLIC_KEY) sauf siskipSignatureVerificationvaut true. skipSignatureVerificationest réservé aux tests locaux.- Si vous utilisez le niveau gratuit de ngrok, définissez
publicUrlsur l’URL ngrok exacte ; la vérification de signature est toujours appliquée. tunnel.allowNgrokFreeTierLoopbackBypass: trueautorise les webhooks Twilio avec des signatures invalides uniquement lorsquetunnel.provider="ngrok"etserve.bindest en loopback (agent local ngrok). À utiliser uniquement pour le développement local.- Les URL ngrok du niveau gratuit peuvent changer ou ajouter un comportement interstitiel ; si
publicUrldérive, les signatures Twilio échoueront. En production, préférez un domaine stable ou Tailscale funnel. - Valeurs de sécurité par défaut du streaming :
streaming.preStartTimeoutMsferme les sockets qui n’envoient jamais de tramestartvalide.
streaming.maxPendingConnectionsplafonne le total des sockets pré-start non authentifiés.streaming.maxPendingConnectionsPerIpplafonne les sockets pré-start non authentifiés par IP source.streaming.maxConnectionsplafonne le total des sockets ouverts de flux média (en attente + actifs).- Le repli runtime accepte encore pour l’instant ces anciennes clés voice-call, mais le chemin de réécriture est
openclaw doctor --fixet le shim de compatibilité est temporaire.
Transcription en streaming
streaming sélectionne un fournisseur de transcription temps réel pour l’audio d’appel en direct.
Comportement actuel du runtime :
streaming.providerest facultatif. S’il n’est pas défini, Voice Call utilise le premier fournisseur de transcription temps réel enregistré.- Aujourd’hui, le fournisseur intégré est OpenAI, enregistré par le plugin intégré
openai. - La configuration brute possédée par le fournisseur se trouve sous
streaming.providers.<providerId>. - Si
streaming.providerpointe vers un fournisseur non enregistré, ou si aucun fournisseur de transcription temps réel n’est enregistré, Voice Call journalise un avertissement et ignore le streaming média au lieu de faire échouer tout le plugin.
- Clé API :
streaming.providers.openai.apiKeyouOPENAI_API_KEY - modèle :
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
Nettoyeur d’appels obsolètes
UtilisezstaleCallReaperSeconds pour terminer les appels qui ne reçoivent jamais de webhook terminal
(par exemple, les appels en mode notify qui ne se terminent jamais). La valeur par défaut est 0
(désactivé).
Plages recommandées :
- Production :
120–300secondes pour les flux de style notify. - Gardez cette valeur supérieure à
maxDurationSecondsafin que les appels normaux puissent se terminer. Un bon point de départ estmaxDurationSeconds + 30–60secondes.
Sécurité du webhook
Lorsqu’un proxy ou un tunnel se trouve devant la Gateway, le plugin reconstruit l’URL publique pour la vérification de signature. Ces options contrôlent les en-têtes transférés considérés comme fiables.webhookSecurity.allowedHosts définit une liste d’autorisation des hôtes provenant des en-têtes de forwarding.
webhookSecurity.trustForwardingHeaders fait confiance aux en-têtes transférés sans liste d’autorisation.
webhookSecurity.trustedProxyIPs ne fait confiance aux en-têtes transférés que lorsque l’IP
distante de la requête correspond à la liste.
La protection contre la relecture de webhook est activée pour Twilio et Plivo. Les requêtes de webhook
valides rejouées sont reconnues mais ignorées pour les effets de bord.
Les tours de conversation Twilio incluent un jeton par tour dans les callbacks <Gather>, de sorte que
les callbacks vocaux obsolètes/rejoués ne peuvent pas satisfaire un tour de transcription plus récent en attente.
Les requêtes webhook non authentifiées sont rejetées avant la lecture du corps lorsque les
en-têtes de signature requis du fournisseur sont absents.
Le webhook voice-call utilise le profil partagé de corps pré-auth (64 KB / 5 secondes)
plus un plafond d’opérations en vol par IP avant la vérification de signature.
Exemple avec un hôte public stable :
TTS pour les appels
Voice Call utilise la configuration cœurmessages.tts pour la
synthèse vocale en streaming sur les appels. Vous pouvez la surcharger sous la configuration du plugin avec la
même forme — elle est fusionnée en profondeur avec messages.tts.
- Les anciennes clés
tts.<provider>dans la configuration du plugin (openai,elevenlabs,microsoft,edge) sont automatiquement migrées verstts.providers.<provider>au chargement. Préférez la formeprovidersdans la configuration commitée. - Microsoft speech est ignoré pour les appels vocaux (l’audio téléphonique a besoin de PCM ; le transport Microsoft actuel n’expose pas de sortie PCM téléphonique).
- Le TTS cœur est utilisé lorsque le streaming média Twilio est activé ; sinon les appels se replient sur les voix natives du fournisseur.
- Si un flux média Twilio est déjà actif, Voice Call ne se replie pas sur TwiML
<Say>. Si le TTS téléphonique n’est pas disponible dans cet état, la demande de lecture échoue au lieu de mélanger deux chemins de lecture. - Lorsque le TTS téléphonique se replie sur un fournisseur secondaire, Voice Call journalise un avertissement avec la chaîne de fournisseurs (
from,to,attempts) pour le débogage.
Plus d’exemples
Utiliser uniquement le TTS cœur (pas de surcharge) :Appels entrants
La politique des appels entrants est par défautdisabled. Pour activer les appels entrants, définissez :
inboundPolicy: "allowlist" est un filtrage de l’identifiant appelant à faible assurance. Le plugin
normalise la valeur From fournie par le fournisseur et la compare à allowFrom.
La vérification du webhook authentifie la remise par le fournisseur et l’intégrité de la charge utile, mais
elle ne prouve pas la propriété du numéro appelant PSTN/VoIP. Traitez allowFrom comme
un filtrage d’identifiant appelant, pas comme une identité forte de l’appelant.
Les réponses automatiques utilisent le système d’agent. Réglez-les avec :
responseModelresponseSystemPromptresponseTimeoutMs
Contrat de sortie parlée
Pour les réponses automatiques, Voice Call ajoute un contrat strict de sortie parlée au prompt système :{"spoken":"..."}
- Ignore les charges utiles marquées comme contenu de raisonnement/erreur.
- Analyse le JSON direct, le JSON fenced ou les clés
"spoken"inline. - Se replie sur le texte brut et supprime les paragraphes initiaux probables de planification/métadonnées.
Comportement de démarrage de conversation
Pour les appels sortantsconversation, la gestion du premier message est liée à l’état de lecture live :
- La suppression de file en cas d’interruption et la réponse automatique ne sont supprimées que pendant la lecture active du message d’accueil initial.
- Si la lecture initiale échoue, l’appel retourne à l’état
listeninget le message initial reste en file d’attente pour une nouvelle tentative. - La lecture initiale pour le streaming Twilio démarre à la connexion du flux sans délai supplémentaire.
Délai de grâce de déconnexion du flux Twilio
Lorsqu’un flux média Twilio se déconnecte, Voice Call attend2000ms avant de terminer automatiquement l’appel :
- Si le flux se reconnecte pendant cette fenêtre, la fin automatique est annulée.
- Si aucun flux n’est réenregistré après la période de grâce, l’appel est terminé pour éviter les appels actifs bloqués.
CLI
latency lit calls.jsonl depuis le chemin de stockage voice-call par défaut. Utilisez
--file <path> pour pointer vers un autre journal et --last <n> pour limiter l’analyse
aux N derniers enregistrements (200 par défaut). La sortie inclut p50/p90/p99 pour la
latence par tour et les temps d’attente d’écoute.
Outil d’agent
Nom de l’outil :voice_call
Actions :
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 Gateway
voicecall.initiate(to?,message,mode?)voicecall.continue(callId,message)voicecall.speak(callId,message)voicecall.end(callId)voicecall.status(callId)