mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 02:17:26 +00:00
The previous migration to tsdown was reverted because it caused a ~20x slowdown when running OpenClaw from the repo. @hyf0 investigated and found that simply renaming the `dist` folder also caused the same slowdown. It turns out the Plugin script loader has a bunch of voodoo vibe logic to determine if it should load files from source and compile them, or if it should load them from dist. When building with tsdown, the filesystem layout is different (bundled), and so some files weren't in the right location, and the Plugin script loader decided to compile source files from scratch using Jiti. The new implementation uses tsdown to embed `NODE_ENV: 'production'`, which we now use to determine if we are running OpenClaw from a "production environmen" (ie. from dist). This removes the slop in favor of a deterministic toggle, and doesn't rely on directory names or similar. There is some code reaching into `dist` to load specific modules, primarily in the voice-call extension, which I simplified into loading an "officially" exported `extensionAPI.js` file. With tsdown, entry points need to be explicitly configured, so we should be able to avoid sloppy code reaching into internals from now on. This might break some existing users, but if it does, it's because they were using "private" APIs.
@openclaw/voice-call
Official Voice Call plugin for OpenClaw.
Providers:
- Twilio (Programmable Voice + Media Streams)
- Telnyx (Call Control v2)
- Plivo (Voice API + XML transfer + GetInput speech)
- Mock (dev/no network)
Docs: https://docs.openclaw.ai/plugins/voice-call
Plugin system: https://docs.openclaw.ai/plugin
Install (local dev)
Option A: install via OpenClaw (recommended)
openclaw plugins install @openclaw/voice-call
Restart the Gateway afterwards.
Option B: copy into your global extensions folder (dev)
mkdir -p ~/.openclaw/extensions
cp -R extensions/voice-call ~/.openclaw/extensions/voice-call
cd ~/.openclaw/extensions/voice-call && pnpm install
Config
Put under plugins.entries.voice-call.config:
{
provider: "twilio", // or "telnyx" | "plivo" | "mock"
fromNumber: "+15550001234",
toNumber: "+15550005678",
twilio: {
accountSid: "ACxxxxxxxx",
authToken: "your_token",
},
plivo: {
authId: "MAxxxxxxxxxxxxxxxxxxxx",
authToken: "your_token",
},
// Webhook server
serve: {
port: 3334,
path: "/voice/webhook",
},
// Public exposure (pick one):
// publicUrl: "https://example.ngrok.app/voice/webhook",
// tunnel: { provider: "ngrok" },
// tailscale: { mode: "funnel", path: "/voice/webhook" }
outbound: {
defaultMode: "notify", // or "conversation"
},
streaming: {
enabled: true,
streamPath: "/voice/stream",
},
}
Notes:
- Twilio/Telnyx/Plivo require a publicly reachable webhook URL.
mockis a local dev provider (no network calls).tunnel.allowNgrokFreeTierLoopbackBypass: trueallows Twilio webhooks with invalid signatures only whentunnel.provider="ngrok"andserve.bindis loopback (ngrok local agent). Use for local dev only.
TTS for calls
Voice Call uses the core messages.tts configuration (OpenAI or ElevenLabs) for
streaming speech on calls. You can override it under the plugin config with the
same shape — overrides deep-merge with messages.tts.
{
tts: {
provider: "openai",
openai: {
voice: "alloy",
},
},
}
Notes:
- Edge TTS is ignored for voice calls (telephony audio needs PCM; Edge output is unreliable).
- Core TTS is used when Twilio media streaming is enabled; otherwise calls fall back to provider native voices.
CLI
openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"
openclaw voicecall continue --call-id <id> --message "Any questions?"
openclaw voicecall speak --call-id <id> --message "One moment"
openclaw voicecall end --call-id <id>
openclaw voicecall status --call-id <id>
openclaw voicecall tail
openclaw voicecall expose --mode funnel
Tool
Tool name: voice_call
Actions:
initiate_call(message, to?, mode?)continue_call(callId, message)speak_to_user(callId, message)end_call(callId)get_status(callId)
Gateway RPC
voicecall.initiate(to?, message, mode?)voicecall.continue(callId, message)voicecall.speak(callId, message)voicecall.end(callId)voicecall.status(callId)
Notes
- Uses webhook signature verification for Twilio/Telnyx/Plivo.
responseModel/responseSystemPromptcontrol AI auto-responses.- Media streaming requires
wsand OpenAI Realtime API key.