mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 21:07:01 -06:00
edecdbd05e
* refactor(config): consolidate media model lists * refactor(config): unify memory configuration * refactor(config): consolidate TTS ownership * refactor(config): move typing policy to agents * refactor(config): retire product-level config surfaces * refactor(config): share scoped tool policy type * chore(config): refresh generated baselines * fix(config): honor agent typing overrides * fix(config): migrate sibling config consumers * refactor(infra): keep base64url decoder private * fix(config): strip invalid legacy TTS values * chore(config): refresh rebased baseline hash * fix(doctor): route legacy messages.tts.realtime voice to talk during tts move * refactor(config): polish final layout names * refactor(config): freeze retired tuning defaults * feat(config): add fast mode default symmetry * refactor(config): key agent entries by id * docs(config): update final layout reference * test(config): cover final layout migrations * chore(config): refresh final layout baselines * fix(config): align final layout runtime readers * fix(config): align remaining readers * fix(config): stabilize final layout migrations * fix(config): finalize config projection proof * fix(config): address final layout review * docs(release): preserve historical config names * fix(config): complete keyed agent migration * fix(config): close final migration gaps * fix(config): finish full-branch review * fix(config): complete runtime secret detection * fix(config): close final review findings * fix(config): finish canonical docs and heartbeat migration * fix(config): integrate latest main after rebase * refactor(env): isolate test-only controls * refactor(env): isolate build and development controls * refactor(env): collapse process identity indirection * refactor(env): remove duplicate config and temp aliases * docs(env): define the operator-facing allowlist * ci(env): ratchet production variable count * fix(env): remove stale provider helper import * fix(env): make ratchet sorting explicit * test(env): keep test seam in dead-code audit * test(env): cover ratchet growth and boundary; document surface budgets * docs(config): document tier-eval consolidations * docs(config): clarify speech preference ownership * test(memory): align retired tuning fixtures * refactor(memory): freeze engine heuristics * refactor(config): apply tier-eval tranche * refactor(tts): move persona shaping to providers * refactor(compaction): move prompt policy to providers * test(config): align hookified prompt fixtures * chore(deadcode): classify test-only exports * chore(github): remove unused spawn helper * chore(deadcode): classify queue diagnostics * chore(deadcode): remove unused lane snapshot export * chore(plugin-sdk): ratchet consolidated surface * fix(config): integrate latest main after rebase
166 lines
5.5 KiB
Markdown
166 lines
5.5 KiB
Markdown
# @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/tools/plugin`
|
|
|
|
## Install
|
|
|
|
```bash
|
|
openclaw plugins install @openclaw/voice-call
|
|
```
|
|
|
|
Restart the Gateway afterwards.
|
|
|
|
## Local dev install
|
|
|
|
```bash
|
|
PLUGIN_HOME=~/.openclaw/extensions
|
|
mkdir -p "$PLUGIN_HOME"
|
|
cp -R <local-plugin-checkout> "$PLUGIN_HOME/voice-call"
|
|
cd "$PLUGIN_HOME/voice-call" && pnpm install
|
|
```
|
|
|
|
## Config
|
|
|
|
Put under `plugins.entries.voice-call.config`:
|
|
|
|
```json5
|
|
{
|
|
provider: "twilio", // or "telnyx" | "plivo" | "mock"
|
|
fromNumber: "+15550001234",
|
|
toNumber: "+15550005678",
|
|
sessionScope: "per-phone", // or "per-call"
|
|
|
|
twilio: {
|
|
accountSid: "ACxxxxxxxx",
|
|
authToken: "your_token",
|
|
},
|
|
|
|
telnyx: {
|
|
apiKey: "KEYxxxx",
|
|
connectionId: "CONNxxxx",
|
|
// Telnyx webhook public key from the Telnyx Mission Control Portal
|
|
// (Base64 string; can also be set via TELNYX_PUBLIC_KEY).
|
|
publicKey: "...",
|
|
},
|
|
|
|
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"
|
|
},
|
|
|
|
// Optional response agent workspace. Defaults to "main".
|
|
agentId: "main",
|
|
|
|
streaming: {
|
|
enabled: true,
|
|
// optional; if omitted, Voice Call picks the first registered
|
|
// realtime-transcription provider by autoSelectOrder
|
|
provider: "<realtime-transcription-provider-id>",
|
|
streamPath: "/voice/stream",
|
|
providers: {
|
|
"<realtime-transcription-provider-id>": {
|
|
// provider-owned options
|
|
},
|
|
},
|
|
preStartTimeoutMs: 5000,
|
|
maxPendingConnections: 32,
|
|
maxPendingConnectionsPerIp: 4,
|
|
maxConnections: 128,
|
|
},
|
|
}
|
|
```
|
|
|
|
Notes:
|
|
|
|
- Twilio/Telnyx/Plivo require a **publicly reachable** webhook URL.
|
|
- Twilio defaults to US1. For a non-US Region, set `twilio.region` to `ie1` or `au1` and use credentials created in that Region; see [Twilio's regional REST API guide](https://www.twilio.com/docs/global-infrastructure/using-the-twilio-rest-api-in-a-non-us-region).
|
|
- `mock` is a local dev provider (no network calls).
|
|
- Telnyx requires `telnyx.publicKey` (or `TELNYX_PUBLIC_KEY`) unless `skipSignatureVerification` is true.
|
|
- Runtime accepts canonical config only. If older configs still use `provider: "log"`, `twilio.from`, or legacy `streaming.*` OpenAI keys, run `openclaw doctor --fix` to rewrite them.
|
|
- advanced webhook, streaming, and tunnel notes: `https://docs.openclaw.ai/plugins/voice-call`
|
|
- `responseModel` is optional. When unset, voice responses use the runtime default model.
|
|
- `sessionScope` defaults to `per-phone`, preserving caller memory across calls. Use `per-call` for reception, booking, IVR, and bridge flows where each carrier call should start fresh.
|
|
- `realtime.consultThinkingLevel` is optional. When set, it overrides the thinking level used by the model behind realtime `openclaw_agent_consult` calls.
|
|
- `realtime.consultFastMode` is optional. When set, it toggles fast mode for realtime `openclaw_agent_consult` calls.
|
|
|
|
## Stale call reaper
|
|
|
|
See the plugin docs for recommended ranges and production examples:
|
|
`https://docs.openclaw.ai/plugins/voice-call#stale-call-reaper`
|
|
|
|
## TTS for calls
|
|
|
|
Voice Call uses the core `tts` configuration for
|
|
streaming speech on calls. Override examples and provider caveats live here:
|
|
`https://docs.openclaw.ai/plugins/voice-call#tts-for-calls`
|
|
|
|
## CLI
|
|
|
|
```bash
|
|
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 --json
|
|
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.
|
|
- Adds replay protection for Twilio and Plivo webhooks (valid duplicate callbacks are ignored safely).
|
|
- Twilio speech turns include a per-turn token so stale/replayed callbacks cannot complete a newer turn.
|
|
- `responseModel` / `responseSystemPrompt` control AI auto-responses.
|
|
- Voice-call auto-responses enforce a spoken JSON contract (`{"spoken":"..."}`) and filter reasoning/meta output before playback.
|
|
- While a Twilio stream is active, playback does not fall back to TwiML `<Say>`; stream-TTS failures fail the playback request.
|
|
- Outbound conversation calls suppress barge-in only while the initial greeting is actively speaking, then re-enable normal interruption.
|
|
- Twilio stream disconnect auto-end uses a short grace window so quick reconnects do not end the call.
|
|
- Realtime provider selection is generic. Configure `streaming.provider` / `realtime.provider` and put provider-owned options under `providers.<id>`.
|