twilio (Programmable Voice + Media Streams),
telnyx (Call Control v2), plivo (Voice API + XML transfer + GetInput
speech), mock (dev/tanpa jaringan).
Plugin Voice Call berjalan di dalam proses Gateway. Jika Anda menggunakan
Gateway jarak jauh, instal dan konfigurasikan Plugin pada mesin yang menjalankan
Gateway, lalu mulai ulang Gateway untuk memuatnya.
Mulai cepat
Instal Plugin
- Dari npm
- Dari folder lokal (dev)
Konfigurasikan penyedia dan Webhook
Tetapkan konfigurasi di bawah
plugins.entries.voice-call.config (lihat
Konfigurasi di bawah untuk bentuk lengkapnya). Minimal:
provider, kredensial penyedia, fromNumber, dan URL Webhook yang dapat
dijangkau publik.Verifikasi setup
streaming atau realtime) yang aktif. Gunakan
--json untuk skrip.Konfigurasi
Jikaenabled: true tetapi penyedia yang dipilih tidak memiliki kredensial,
startup Gateway mencatat peringatan setup-belum-lengkap dengan kunci yang hilang dan
melewati startup runtime. Perintah, panggilan RPC, dan tool agen tetap
mengembalikan konfigurasi penyedia yang hilang secara persis saat digunakan.
Kredensial voice-call menerima SecretRefs.
plugins.entries.voice-call.config.twilio.authToken, plugins.entries.voice-call.config.realtime.providers.*.apiKey, plugins.entries.voice-call.config.streaming.providers.*.apiKey, dan plugins.entries.voice-call.config.tts.providers.*.apiKey diselesaikan melalui permukaan SecretRef standar; lihat Permukaan kredensial SecretRef.Catatan paparan dan keamanan penyedia
Catatan paparan dan keamanan penyedia
- Twilio, Telnyx, dan Plivo semuanya membutuhkan URL Webhook yang dapat dijangkau publik.
mockadalah penyedia dev lokal (tanpa panggilan jaringan).- Telnyx membutuhkan
telnyx.publicKey(atauTELNYX_PUBLIC_KEY) kecualiskipSignatureVerificationbernilai true. skipSignatureVerificationhanya untuk pengujian lokal.- Pada tier gratis ngrok, tetapkan
publicUrlke URL ngrok yang persis; verifikasi tanda tangan selalu diberlakukan. tunnel.allowNgrokFreeTierLoopbackBypass: truemengizinkan Webhook Twilio dengan tanda tangan tidak valid hanya saattunnel.provider="ngrok"danserve.bindadalah loopback (agen lokal ngrok). Hanya untuk dev lokal.- URL tier gratis Ngrok dapat berubah atau menambahkan perilaku interstitial; jika
publicUrlbergeser, tanda tangan Twilio gagal. Produksi: pilih domain stabil atau funnel Tailscale.
Batas koneksi streaming
Batas koneksi streaming
streaming.preStartTimeoutMsmenutup soket yang tidak pernah mengirim framestartyang valid.streaming.maxPendingConnectionsmembatasi total soket pra-start yang belum terautentikasi.streaming.maxPendingConnectionsPerIpmembatasi soket pra-start yang belum terautentikasi per IP sumber.streaming.maxConnectionsmembatasi total soket media stream yang terbuka (tertunda + aktif).
Migrasi konfigurasi legacy
Migrasi konfigurasi legacy
Konfigurasi lama yang menggunakan
provider: "log", twilio.from, atau kunci OpenAI
streaming.* legacy ditulis ulang oleh openclaw doctor --fix.
Fallback runtime masih menerima kunci voice-call lama untuk saat ini, tetapi
jalur penulisan ulangnya adalah openclaw doctor --fix dan shim kompatibilitasnya
bersifat sementara.Kunci streaming yang dimigrasikan otomatis:streaming.sttProvider→streaming.providerstreaming.openaiApiKey→streaming.providers.openai.apiKeystreaming.sttModel→streaming.providers.openai.modelstreaming.silenceDurationMs→streaming.providers.openai.silenceDurationMsstreaming.vadThreshold→streaming.providers.openai.vadThreshold
Cakupan sesi
Secara bawaan, Voice Call menggunakansessionScope: "per-phone" sehingga panggilan berulang dari
penelepon yang sama mempertahankan memori percakapan. Tetapkan sessionScope: "per-call" saat
setiap panggilan operator harus dimulai dengan konteks baru, misalnya alur resepsionis,
pemesanan, IVR, atau bridge Google Meet saat nomor telepon yang sama mungkin
mewakili rapat yang berbeda.
Voice Call menyimpan kunci sesi yang dihasilkan di bawah namespace agen yang dikonfigurasi
(agent:<agentId>:voice:*) sehingga memori panggilan bertahan melewati kanonikalisasi
kunci sesi Gateway setelah restart. Kunci integrasi eksplisit mentah menggunakan
namespace agen yang sama. Kunci kanonis agent:<configuredAgentId>:* mempertahankan pemilik itu,
dan alias utamanya menghormati session.mainKey inti dan cakupan global. Input
agent:* asing atau salah bentuk dicakup sebagai kunci buram di bawah agen yang dikonfigurasi;
global dan unknown tetap menjadi sentinel global. Startup Gateway mempromosikan kunci
mentah lama di store bawaan atau bertemplat {agentId} saat path membuktikan satu
pemilik. Pada store kustom tetap, baris legacy yang ambigu dibiarkan tidak tersentuh karena
tidak berisi cukup informasi untuk memilih pemilik; panggilan baru menggunakan
riwayat kanonis bercakupan agen.
Percakapan suara realtime
realtime memilih penyedia suara realtime full-duplex untuk audio panggilan
langsung. Ini terpisah dari streaming, yang hanya meneruskan audio ke
penyedia transkripsi realtime.
Perilaku runtime saat ini:
realtime.enableddidukung untuk Twilio Media Streams.realtime.providerbersifat opsional. Jika tidak ditetapkan, Voice Call menggunakan penyedia suara realtime terdaftar pertama.- Penyedia suara realtime bawaan: Google Gemini Live (
google) dan OpenAI (openai), didaftarkan oleh Plugin penyedia masing-masing. - Konfigurasi mentah milik penyedia berada di bawah
realtime.providers.<providerId>. - Voice Call mengekspos tool realtime bersama
openclaw_agent_consultsecara bawaan. Model realtime dapat memanggilnya saat penelepon meminta penalaran lebih mendalam, informasi terkini, atau tool OpenClaw normal. realtime.consultPolicysecara opsional menambahkan panduan tentang kapan model realtime harus memanggilopenclaw_agent_consult.realtime.agentContext.enablednonaktif secara bawaan. Saat diaktifkan, Voice Call menyisipkan identitas agen terbatas dan kapsul file workspace terpilih ke instruksi penyedia realtime saat setup sesi.realtime.fastContext.enablednonaktif secara bawaan. Saat diaktifkan, Voice Call terlebih dahulu mencari konteks memori/sesi terindeks untuk pertanyaan konsultasi dan mengembalikan cuplikan tersebut ke model realtime dalamrealtime.fastContext.timeoutMssebelum fallback ke agen konsultasi penuh hanya jikarealtime.fastContext.fallbackToConsultbernilai true.- Jika
realtime.providermenunjuk ke penyedia yang tidak terdaftar, atau tidak ada penyedia suara realtime yang terdaftar sama sekali, Voice Call mencatat peringatan dan melewati media realtime alih-alih menggagalkan seluruh Plugin. - Kunci sesi konsultasi menggunakan ulang sesi panggilan yang tersimpan saat tersedia, lalu fallback ke
sessionScopeyang dikonfigurasi (per-phonesecara bawaan, atauper-calluntuk panggilan terisolasi).
Kebijakan tool
realtime.toolPolicy mengontrol run konsultasi:
| Kebijakan | Perilaku |
|---|---|
safe-read-only | Mengekspos tool konsultasi dan membatasi agen reguler ke read, web_search, web_fetch, x_search, memory_search, dan memory_get. |
owner | Mengekspos tool konsultasi dan membiarkan agen reguler menggunakan kebijakan tool agen normal. |
none | Tidak mengekspos tool konsultasi. realtime.tools kustom tetap diteruskan ke penyedia realtime. |
realtime.consultPolicy hanya mengontrol instruksi model realtime:
| Kebijakan | Panduan |
|---|---|
auto | Pertahankan prompt bawaan dan biarkan penyedia memutuskan kapan memanggil tool konsultasi. |
substantive | Jawab penghubung percakapan sederhana secara langsung dan konsultasikan sebelum fakta, memori, tool, atau konteks. |
always | Konsultasikan sebelum setiap jawaban substantif. |
Konteks suara agen
Aktifkanrealtime.agentContext ketika jembatan suara harus terdengar seperti
agen OpenClaw yang dikonfigurasi tanpa membayar perjalanan pulang-pergi konsultasi
agen penuh pada giliran biasa. Kapsul konteks ditambahkan satu kali saat sesi realtime
dibuat, sehingga tidak menambah latensi per giliran. Panggilan ke
openclaw_agent_consult tetap menjalankan agen OpenClaw penuh dan harus digunakan
untuk pekerjaan alat, informasi terkini, pencarian memori, atau status workspace.
Contoh penyedia realtime
- Google Gemini Live
- OpenAI
Default: kunci API dari
realtime.providers.google.apiKey,
GEMINI_API_KEY, atau GOOGLE_GENERATIVE_AI_API_KEY; model
gemini-2.5-flash-native-audio-preview-12-2025; suara Kore.
sessionResumption dan contextWindowCompression aktif secara default untuk panggilan yang lebih panjang
dan dapat disambungkan ulang. Gunakan silenceDurationMs, startSensitivity, dan
endSensitivity untuk menyesuaikan pengambilan giliran yang lebih cepat pada audio telepon.Transkripsi streaming
streaming memilih penyedia transkripsi realtime untuk audio panggilan langsung.
Perilaku runtime saat ini:
streaming.providerbersifat opsional. Jika tidak disetel, Panggilan Suara menggunakan penyedia transkripsi realtime terdaftar pertama.- Penyedia transkripsi realtime bawaan: Deepgram (
deepgram), ElevenLabs (elevenlabs), Mistral (mistral), OpenAI (openai), dan xAI (xai), yang didaftarkan oleh Plugin penyedia masing-masing. - Konfigurasi mentah milik penyedia berada di bawah
streaming.providers.<providerId>. - Setelah Twilio mengirim pesan
startstream yang diterima, Panggilan Suara segera mendaftarkan stream, mengantrekan media masuk melalui penyedia transkripsi saat penyedia tersambung, dan memulai sapaan awal hanya setelah transkripsi realtime siap. - Jika
streaming.providermengarah ke penyedia yang tidak terdaftar, atau tidak ada yang terdaftar, Panggilan Suara mencatat peringatan dan melewati streaming media alih-alih menggagalkan seluruh Plugin.
Contoh penyedia streaming
- OpenAI
- xAI
Default: kunci API
streaming.providers.openai.apiKey atau
OPENAI_API_KEY; model gpt-4o-transcribe; silenceDurationMs: 800;
vadThreshold: 0.5.TTS untuk panggilan
Panggilan Suara menggunakan konfigurasi intimessages.tts untuk streaming
ucapan pada panggilan. Anda dapat menimpanya di bawah konfigurasi Plugin dengan
bentuk yang sama — konfigurasi ini digabungkan secara mendalam dengan messages.tts.
- Kunci lama
tts.<provider>di dalam konfigurasi Plugin (openai,elevenlabs,microsoft,edge) diperbaiki olehopenclaw doctor --fix; konfigurasi yang di-commit harus menggunakantts.providers.<provider>. - TTS inti digunakan saat streaming media Twilio diaktifkan; jika tidak, panggilan kembali ke suara native penyedia.
- Jika stream media Twilio sudah aktif, Panggilan Suara tidak kembali ke TwiML
<Say>. Jika TTS telepon tidak tersedia dalam status itu, permintaan pemutaran gagal alih-alih mencampur dua jalur pemutaran. - Saat TTS telepon kembali ke penyedia sekunder, Panggilan Suara mencatat peringatan dengan rantai penyedia (
from,to,attempts) untuk debugging. - Saat barge-in Twilio atau pembongkaran stream membersihkan antrean TTS yang tertunda, permintaan pemutaran yang diantrekan diselesaikan alih-alih membiarkan penelepon menunggu penyelesaian pemutaran tanpa akhir.
Contoh TTS
- Hanya TTS inti
- Timpa ke ElevenLabs (hanya panggilan)
- Penimpaan model OpenAI (deep-merge)
Panggilan masuk
Kebijakan masuk default adalahdisabled. Untuk mengaktifkan panggilan masuk, setel:
responseModel,
responseSystemPrompt, dan responseTimeoutMs.
Perutean per nomor
Gunakannumbers ketika satu Plugin Panggilan Suara menerima panggilan untuk beberapa nomor telepon
dan setiap nomor harus berperilaku seperti saluran yang berbeda. Misalnya, satu
nomor dapat menggunakan asisten pribadi santai sementara nomor lain menggunakan persona
bisnis, agen respons berbeda, dan suara TTS berbeda.
Rute dipilih dari nomor To yang ditelepon dan disediakan penyedia. Kunci harus berupa
nomor E.164. Saat panggilan tiba, Panggilan Suara menyelesaikan rute yang cocok satu kali,
menyimpan rute yang cocok pada catatan panggilan, dan menggunakan kembali konfigurasi efektif itu
untuk sapaan, jalur respons otomatis klasik, jalur konsultasi realtime, dan pemutaran
TTS. Jika tidak ada rute yang cocok, konfigurasi Panggilan Suara global digunakan.
Panggilan keluar tidak menggunakan numbers; teruskan target keluar, pesan, dan
sesi secara eksplisit saat memulai panggilan.
Penimpaan rute saat ini mendukung:
inboundGreetingttsagentIdresponseModelresponseSystemPromptresponseTimeoutMs
tts digabungkan secara mendalam di atas konfigurasi tts Panggilan Suara global, sehingga
biasanya Anda dapat menimpa hanya suara penyedia:
Kontrak keluaran lisan
Untuk respons otomatis, Panggilan Suara menambahkan kontrak keluaran lisan yang ketat ke prompt sistem:- Mengabaikan payload yang ditandai sebagai konten penalaran/kesalahan.
- Mengurai JSON langsung, JSON berpagar, atau kunci
"spoken"inline. - Kembali ke teks biasa dan menghapus paragraf pengantar perencanaan/meta yang kemungkinan ada.
Perilaku awal percakapan
Untuk panggilanconversation keluar, penanganan pesan pertama terikat pada status
pemutaran langsung:
- Pembersihan antrean barge-in dan respons otomatis ditekan hanya saat sapaan awal sedang aktif diucapkan.
- Jika pemutaran awal gagal, panggilan kembali ke
listeningdan pesan awal tetap diantrekan untuk dicoba ulang. - Pemutaran awal untuk streaming Twilio dimulai saat stream tersambung tanpa penundaan tambahan.
- Barge-in membatalkan pemutaran aktif dan membersihkan entri TTS Twilio yang diantrekan tetapi belum diputar. Entri yang dibersihkan diselesaikan sebagai dilewati, sehingga logika respons lanjutan dapat berlanjut tanpa menunggu audio yang tidak akan pernah diputar.
- Percakapan suara realtime menggunakan giliran pembuka milik stream realtime sendiri. Panggilan Suara tidak memposting pembaruan TwiML
<Say>lama untuk pesan awal itu, sehingga sesi<Connect><Stream>keluar tetap terpasang.
Masa tenggang pemutusan stream Twilio
Saat stream media Twilio terputus, Voice Call menunggu 2000 ms sebelum mengakhiri panggilan secara otomatis:- Jika stream tersambung kembali selama jendela waktu tersebut, pengakhiran otomatis dibatalkan.
- Jika tidak ada stream yang mendaftar ulang setelah masa tenggang, panggilan diakhiri untuk mencegah panggilan aktif yang macet.
Pembersih panggilan basi
GunakanstaleCallReaperSeconds untuk mengakhiri panggilan yang tidak pernah menerima
Webhook terminal (misalnya, panggilan mode notifikasi yang tidak pernah selesai). Nilai bawaan
adalah 0 (dinonaktifkan).
Rentang yang direkomendasikan:
- Produksi:
120–300detik untuk alur bergaya notifikasi. - Pertahankan nilai ini lebih tinggi daripada
maxDurationSecondsagar panggilan normal dapat selesai. Titik awal yang baik adalahmaxDurationSeconds + 30–60detik.
Keamanan Webhook
Ketika proxy atau tunnel berada di depan Gateway, Plugin merekonstruksi URL publik untuk verifikasi tanda tangan. Opsi-opsi ini mengontrol header penerusan mana yang dipercaya:Izinkan host dari header penerusan.
Percayai header yang diteruskan tanpa daftar izin.
Hanya percayai header yang diteruskan ketika IP jarak jauh permintaan cocok dengan daftar.
- Perlindungan pemutaran ulang Webhook diaktifkan untuk Twilio dan Plivo. Permintaan Webhook valid yang diputar ulang diakui tetapi dilewati untuk efek samping.
- Giliran percakapan Twilio menyertakan token per giliran dalam callback
<Gather>, sehingga callback ucapan yang basi/diputar ulang tidak dapat memenuhi giliran transkrip tertunda yang lebih baru. - Permintaan Webhook tanpa autentikasi ditolak sebelum pembacaan body ketika header tanda tangan wajib dari penyedia tidak ada.
- Webhook voice-call menggunakan profil body pra-autentikasi bersama (64 KB / 5 detik) ditambah batas in-flight per IP sebelum verifikasi tanda tangan.
CLI
voicecall didelegasikan
ke runtime voice-call milik Gateway sehingga CLI tidak mengikat server
Webhook kedua. Jika tidak ada Gateway yang dapat dijangkau, perintah kembali ke
runtime CLI mandiri.
latency membaca calls.jsonl dari jalur penyimpanan voice-call bawaan.
Gunakan --file <path> untuk menunjuk ke log lain dan --last <n> untuk membatasi
analisis ke N rekaman terakhir (bawaan 200). Output menyertakan p50/p90/p99
untuk latensi giliran dan waktu tunggu-dengar.
Tool agen
Nama tool:voice_call.
| Tindakan | Argumen |
|---|---|
initiate_call | message, to?, mode?, dtmfSequence? |
continue_call | callId, message |
speak_to_user | callId, message |
send_dtmf | callId, digits |
end_call | callId |
get_status | callId |
RPC Gateway
| Metode | Argumen |
|---|---|
voicecall.initiate | to?, message, mode?, dtmfSequence? |
voicecall.continue | callId, message |
voicecall.speak | callId, message |
voicecall.dtmf | callId, digits |
voicecall.end | callId |
voicecall.status | callId |
dtmfSequence hanya valid dengan mode: "conversation". Panggilan mode notifikasi
sebaiknya menggunakan voicecall.dtmf setelah panggilan ada jika memerlukan digit
setelah tersambung.
Pemecahan masalah
Penyiapan gagal mengekspos Webhook
Jalankan penyiapan dari lingkungan yang sama dengan yang menjalankan Gateway:twilio, telnyx, dan plivo, webhook-exposure harus hijau. publicUrl
yang dikonfigurasi tetap gagal ketika mengarah ke ruang jaringan lokal atau privat,
karena operator tidak dapat memanggil balik ke alamat tersebut. Jangan gunakan
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, atau fd00::/8 sebagai publicUrl.
Panggilan keluar mode notifikasi Twilio mengirim TwiML <Say> awal secara langsung dalam
permintaan create-call, sehingga pesan lisan pertama tidak bergantung pada Twilio
mengambil TwiML Webhook. Webhook publik tetap diperlukan untuk callback status,
panggilan percakapan, DTMF pra-sambung, stream realtime, dan kontrol panggilan
pasca-sambung.
Gunakan satu jalur eksposur publik:
voicecall smoke adalah dry run kecuali Anda meneruskan --yes.
Kredensial penyedia gagal
Periksa penyedia yang dipilih dan kolom kredensial yang diperlukan:- Twilio:
twilio.accountSid,twilio.authToken, danfromNumber, atauTWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKEN, danTWILIO_FROM_NUMBER. - Telnyx:
telnyx.apiKey,telnyx.connectionId,telnyx.publicKey, danfromNumber. - Plivo:
plivo.authId,plivo.authToken, danfromNumber.
Panggilan dimulai tetapi Webhook penyedia tidak masuk
Konfirmasikan konsol penyedia mengarah ke URL Webhook publik yang tepat:publicUrlmengarah ke jalur yang berbeda dariserve.path.- URL tunnel berubah setelah Gateway dimulai.
- Proxy meneruskan permintaan tetapi menghapus atau menulis ulang header host/proto.
- Firewall atau DNS mengarahkan hostname publik ke tempat selain Gateway.
- Gateway dimulai ulang tanpa Plugin Voice Call diaktifkan.
webhookSecurity.allowedHosts ke hostname publik, atau gunakan
webhookSecurity.trustedProxyIPs untuk alamat proxy yang diketahui. Gunakan
webhookSecurity.trustForwardingHeaders hanya ketika batas proxy berada di bawah
kendali Anda.
Verifikasi tanda tangan gagal
Tanda tangan penyedia diperiksa terhadap URL publik yang direkonstruksi OpenClaw dari permintaan masuk. Jika tanda tangan gagal:- Konfirmasikan URL Webhook penyedia sama persis dengan
publicUrl, termasuk skema, host, dan jalur. - Untuk URL tingkat gratis ngrok, perbarui
publicUrlketika hostname tunnel berubah. - Pastikan proxy mempertahankan header host dan proto asli, atau konfigurasikan
webhookSecurity.allowedHosts. - Jangan aktifkan
skipSignatureVerificationdi luar pengujian lokal.
Gabung Google Meet Twilio gagal
Google Meet menggunakan Plugin ini untuk gabung dial-in Twilio. Pertama, verifikasi Voice Call:--dtmf-sequence. Panggilan telepon dapat sehat sementara
rapat menolak atau mengabaikan urutan DTMF yang salah.
Google Meet memulai kaki telepon Twilio melalui voicecall.start dengan
urutan DTMF pra-sambung. Urutan yang diturunkan dari PIN menyertakan
voiceCall.dtmfDelayMs milik Plugin Google Meet sebagai digit tunggu Twilio di depan.
Nilai bawaan adalah 12 detik karena prompt dial-in Meet dapat tiba terlambat. Voice Call kemudian mengarahkan kembali ke
penanganan realtime sebelum salam pembuka diminta.
Gunakan openclaw logs --follow untuk jejak fase langsung. Gabung Twilio Meet
yang sehat mencatat urutan ini:
- Google Meet mendelegasikan gabung Twilio ke Voice Call.
- Voice Call menyimpan TwiML DTMF pra-sambung.
- TwiML awal Twilio digunakan dan disajikan sebelum penanganan realtime.
- Voice Call menyajikan TwiML realtime untuk panggilan Twilio.
- Google Meet meminta ucapan pembuka dengan
voicecall.speaksetelah penundaan pasca-DTMF.
openclaw voicecall tail tetap menampilkan rekaman panggilan yang dipersistenkan; ini berguna untuk
status panggilan dan transkrip, tetapi tidak setiap transisi Webhook/realtime muncul
di sana.
Panggilan realtime tidak memiliki ucapan
Konfirmasikan hanya satu mode audio yang diaktifkan.realtime.enabled dan
streaming.enabled tidak boleh sama-sama true.
Untuk panggilan Twilio realtime, verifikasi juga:
- Plugin penyedia realtime dimuat dan terdaftar.
realtime.providertidak diatur atau menamai penyedia yang terdaftar.- Kunci API penyedia tersedia untuk proses Gateway.
openclaw logs --followmenunjukkan TwiML realtime disajikan, bridge realtime dimulai, dan salam awal diantrekan.