@openclaw/voice-call 2026.3.12 → 2026.5.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -48
- package/api.ts +16 -0
- package/cli-metadata.ts +10 -0
- package/config-api.ts +12 -0
- package/index.test.ts +866 -0
- package/index.ts +374 -147
- package/openclaw.plugin.json +336 -157
- package/package.json +33 -5
- package/runtime-api.ts +20 -0
- package/runtime-entry.ts +1 -0
- package/setup-api.ts +47 -0
- package/src/allowlist.test.ts +18 -0
- package/src/cli.ts +533 -68
- package/src/config-compat.test.ts +120 -0
- package/src/config-compat.ts +227 -0
- package/src/config.test.ts +160 -12
- package/src/config.ts +243 -74
- package/src/core-bridge.ts +2 -147
- package/src/deep-merge.test.ts +40 -0
- package/src/gateway-continue-operation.ts +200 -0
- package/src/http-headers.ts +6 -3
- package/src/manager/context.ts +6 -5
- package/src/manager/events.test.ts +179 -19
- package/src/manager/events.ts +48 -30
- package/src/manager/lifecycle.ts +53 -0
- package/src/manager/lookup.test.ts +52 -0
- package/src/manager/outbound.test.ts +464 -0
- package/src/manager/outbound.ts +148 -55
- package/src/manager/store.ts +18 -6
- package/src/manager/timers.test.ts +129 -0
- package/src/manager/timers.ts +4 -3
- package/src/manager/twiml.test.ts +13 -0
- package/src/manager/twiml.ts +8 -0
- package/src/manager.closed-loop.test.ts +30 -12
- package/src/manager.inbound-allowlist.test.ts +77 -10
- package/src/manager.notify.test.ts +344 -20
- package/src/manager.restore.test.ts +118 -65
- package/src/manager.test-harness.ts +8 -6
- package/src/manager.ts +79 -5
- package/src/media-stream.test.ts +578 -81
- package/src/media-stream.ts +235 -54
- package/src/providers/base.ts +19 -0
- package/src/providers/mock.ts +7 -1
- package/src/providers/plivo.test.ts +50 -6
- package/src/providers/plivo.ts +14 -6
- package/src/providers/shared/call-status.ts +2 -1
- package/src/providers/shared/guarded-json-api.test.ts +106 -0
- package/src/providers/shared/guarded-json-api.ts +1 -1
- package/src/providers/telnyx.test.ts +207 -33
- package/src/providers/telnyx.ts +40 -3
- package/src/providers/twilio/api.test.ts +145 -0
- package/src/providers/twilio/api.ts +67 -16
- package/src/providers/twilio/twiml-policy.ts +6 -10
- package/src/providers/twilio/webhook.ts +1 -1
- package/src/providers/twilio.test.ts +431 -27
- package/src/providers/twilio.ts +230 -77
- package/src/providers/twilio.types.ts +17 -0
- package/src/realtime-defaults.ts +3 -0
- package/src/realtime-fast-context.test.ts +88 -0
- package/src/realtime-fast-context.ts +165 -0
- package/src/realtime-transcription.runtime.ts +4 -0
- package/src/realtime-voice.runtime.ts +5 -0
- package/src/response-generator.test.ts +277 -0
- package/src/response-generator.ts +186 -40
- package/src/response-model.test.ts +71 -0
- package/src/response-model.ts +23 -0
- package/src/runtime.test.ts +351 -0
- package/src/runtime.ts +254 -24
- package/src/telephony-audio.test.ts +61 -0
- package/src/telephony-audio.ts +1 -79
- package/src/telephony-tts.test.ts +133 -12
- package/src/telephony-tts.ts +155 -2
- package/src/test-fixtures.ts +26 -7
- package/src/tts-provider-voice.test.ts +34 -0
- package/src/tts-provider-voice.ts +21 -0
- package/src/tunnel.test.ts +166 -0
- package/src/tunnel.ts +1 -1
- package/src/types.ts +24 -37
- package/src/utils.test.ts +17 -0
- package/src/voice-mapping.test.ts +34 -0
- package/src/voice-mapping.ts +3 -2
- package/src/webhook/realtime-handler.test.ts +598 -0
- package/src/webhook/realtime-handler.ts +485 -0
- package/src/webhook/stale-call-reaper.test.ts +88 -0
- package/src/webhook/stale-call-reaper.ts +5 -0
- package/src/webhook/tailscale.test.ts +214 -0
- package/src/webhook/tailscale.ts +19 -5
- package/src/webhook-exposure.test.ts +33 -0
- package/src/webhook-exposure.ts +84 -0
- package/src/webhook-security.test.ts +245 -126
- package/src/webhook-security.ts +43 -29
- package/src/webhook.hangup-once.lifecycle.test.ts +135 -0
- package/src/webhook.test.ts +1174 -52
- package/src/webhook.ts +513 -100
- package/src/webhook.types.ts +5 -0
- package/src/websocket-test-support.ts +72 -0
- package/tsconfig.json +16 -0
- package/CHANGELOG.md +0 -115
- package/src/providers/index.ts +0 -10
- package/src/providers/stt-openai-realtime.test.ts +0 -42
- package/src/providers/stt-openai-realtime.ts +0 -311
- package/src/providers/tts-openai.test.ts +0 -43
- package/src/providers/tts-openai.ts +0 -221
package/README.md
CHANGED
|
@@ -25,9 +25,10 @@ Restart the Gateway afterwards.
|
|
|
25
25
|
### Option B: copy into your global extensions folder (dev)
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
PLUGIN_HOME=~/.openclaw/extensions
|
|
29
|
+
mkdir -p "$PLUGIN_HOME"
|
|
30
|
+
cp -R <local-plugin-checkout> "$PLUGIN_HOME/voice-call"
|
|
31
|
+
cd "$PLUGIN_HOME/voice-call" && pnpm install
|
|
31
32
|
```
|
|
32
33
|
|
|
33
34
|
## Config
|
|
@@ -73,9 +74,20 @@ Put under `plugins.entries.voice-call.config`:
|
|
|
73
74
|
defaultMode: "notify", // or "conversation"
|
|
74
75
|
},
|
|
75
76
|
|
|
77
|
+
// Optional response agent workspace. Defaults to "main".
|
|
78
|
+
agentId: "main",
|
|
79
|
+
|
|
76
80
|
streaming: {
|
|
77
81
|
enabled: true,
|
|
82
|
+
// optional; if omitted, Voice Call picks the first registered
|
|
83
|
+
// realtime-transcription provider by autoSelectOrder
|
|
84
|
+
provider: "<realtime-transcription-provider-id>",
|
|
78
85
|
streamPath: "/voice/stream",
|
|
86
|
+
providers: {
|
|
87
|
+
"<realtime-transcription-provider-id>": {
|
|
88
|
+
// provider-owned options
|
|
89
|
+
},
|
|
90
|
+
},
|
|
79
91
|
preStartTimeoutMs: 5000,
|
|
80
92
|
maxPendingConnections: 32,
|
|
81
93
|
maxPendingConnectionsPerIp: 4,
|
|
@@ -89,56 +101,20 @@ Notes:
|
|
|
89
101
|
- Twilio/Telnyx/Plivo require a **publicly reachable** webhook URL.
|
|
90
102
|
- `mock` is a local dev provider (no network calls).
|
|
91
103
|
- Telnyx requires `telnyx.publicKey` (or `TELNYX_PUBLIC_KEY`) unless `skipSignatureVerification` is true.
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
- `streaming.preStartTimeoutMs` closes sockets that never send a valid `start` frame.
|
|
97
|
-
- `streaming.maxPendingConnections` caps total unauthenticated pre-start sockets.
|
|
98
|
-
- `streaming.maxPendingConnectionsPerIp` caps unauthenticated pre-start sockets per source IP.
|
|
99
|
-
- `streaming.maxConnections` caps total open media stream sockets (pending + active).
|
|
104
|
+
- If older configs still use `provider: "log"`, `twilio.from`, or legacy `streaming.*` OpenAI keys, run `openclaw doctor --fix` to rewrite them.
|
|
105
|
+
- advanced webhook, streaming, and tunnel notes: `https://docs.openclaw.ai/plugins/voice-call`
|
|
106
|
+
- `responseModel` is optional. When unset, voice responses use the runtime default model.
|
|
100
107
|
|
|
101
108
|
## Stale call reaper
|
|
102
109
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
(disabled).
|
|
106
|
-
|
|
107
|
-
Recommended ranges:
|
|
108
|
-
|
|
109
|
-
- **Production:** `120`–`300` seconds for notify-style flows.
|
|
110
|
-
- Keep this value **higher than `maxDurationSeconds`** so normal calls can
|
|
111
|
-
finish. A good starting point is `maxDurationSeconds + 30–60` seconds.
|
|
112
|
-
|
|
113
|
-
Example:
|
|
114
|
-
|
|
115
|
-
```json5
|
|
116
|
-
{
|
|
117
|
-
staleCallReaperSeconds: 360,
|
|
118
|
-
}
|
|
119
|
-
```
|
|
110
|
+
See the plugin docs for recommended ranges and production examples:
|
|
111
|
+
`https://docs.openclaw.ai/plugins/voice-call#stale-call-reaper`
|
|
120
112
|
|
|
121
113
|
## TTS for calls
|
|
122
114
|
|
|
123
|
-
Voice Call uses the core `messages.tts` configuration
|
|
124
|
-
streaming speech on calls.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```json5
|
|
128
|
-
{
|
|
129
|
-
tts: {
|
|
130
|
-
provider: "openai",
|
|
131
|
-
openai: {
|
|
132
|
-
voice: "alloy",
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
Notes:
|
|
139
|
-
|
|
140
|
-
- Edge TTS is ignored for voice calls (telephony audio needs PCM; Edge output is unreliable).
|
|
141
|
-
- Core TTS is used when Twilio media streaming is enabled; otherwise calls fall back to provider native voices.
|
|
115
|
+
Voice Call uses the core `messages.tts` configuration for
|
|
116
|
+
streaming speech on calls. Override examples and provider caveats live here:
|
|
117
|
+
`https://docs.openclaw.ai/plugins/voice-call#tts-for-calls`
|
|
142
118
|
|
|
143
119
|
## CLI
|
|
144
120
|
|
|
@@ -147,6 +123,7 @@ openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"
|
|
|
147
123
|
openclaw voicecall continue --call-id <id> --message "Any questions?"
|
|
148
124
|
openclaw voicecall speak --call-id <id> --message "One moment"
|
|
149
125
|
openclaw voicecall end --call-id <id>
|
|
126
|
+
openclaw voicecall status --json
|
|
150
127
|
openclaw voicecall status --call-id <id>
|
|
151
128
|
openclaw voicecall tail
|
|
152
129
|
openclaw voicecall expose --mode funnel
|
|
@@ -178,4 +155,9 @@ Actions:
|
|
|
178
155
|
- Adds replay protection for Twilio and Plivo webhooks (valid duplicate callbacks are ignored safely).
|
|
179
156
|
- Twilio speech turns include a per-turn token so stale/replayed callbacks cannot complete a newer turn.
|
|
180
157
|
- `responseModel` / `responseSystemPrompt` control AI auto-responses.
|
|
181
|
-
-
|
|
158
|
+
- Voice-call auto-responses enforce a spoken JSON contract (`{"spoken":"..."}`) and filter reasoning/meta output before playback.
|
|
159
|
+
- While a Twilio stream is active, playback does not fall back to TwiML `<Say>`; stream-TTS failures fail the playback request.
|
|
160
|
+
- Outbound conversation calls suppress barge-in only while the initial greeting is actively speaking, then re-enable normal interruption.
|
|
161
|
+
- Twilio stream disconnect auto-end uses a short grace window so quick reconnects do not end the call.
|
|
162
|
+
- Realtime provider selection is generic. Configure `streaming.provider` / `realtime.provider` and put provider-owned options under `providers.<id>`.
|
|
163
|
+
- Runtime fallback still accepts the old voice-call keys for now, but migration is a doctor step and the compat shim is scheduled to go away in a future release.
|
package/api.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export {
|
|
2
|
+
definePluginEntry,
|
|
3
|
+
fetchWithSsrFGuard,
|
|
4
|
+
type GatewayRequestHandlerOptions,
|
|
5
|
+
isBlockedHostnameOrIp,
|
|
6
|
+
isRequestBodyLimitError,
|
|
7
|
+
type OpenClawPluginApi,
|
|
8
|
+
readRequestBodyWithLimit,
|
|
9
|
+
requestBodyErrorToText,
|
|
10
|
+
type SessionEntry,
|
|
11
|
+
sleep,
|
|
12
|
+
TtsAutoSchema,
|
|
13
|
+
TtsConfigSchema,
|
|
14
|
+
TtsModeSchema,
|
|
15
|
+
TtsProviderSchema,
|
|
16
|
+
} from "./runtime-api.js";
|
package/cli-metadata.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
2
|
+
|
|
3
|
+
export default definePluginEntry({
|
|
4
|
+
id: "voice-call",
|
|
5
|
+
name: "Voice Call",
|
|
6
|
+
description: "Voice call channel plugin",
|
|
7
|
+
register(api) {
|
|
8
|
+
api.registerCli(() => {}, { commands: ["voicecall"] });
|
|
9
|
+
},
|
|
10
|
+
});
|
package/config-api.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Narrow barrel for config compatibility helpers consumed outside the plugin.
|
|
2
|
+
// Keep this separate from api.ts so config migration code does not pull in the
|
|
3
|
+
// full runtime-oriented voice-call surface.
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
VOICE_CALL_LEGACY_CONFIG_REMOVAL_VERSION,
|
|
7
|
+
collectVoiceCallLegacyConfigIssues,
|
|
8
|
+
formatVoiceCallLegacyConfigWarnings,
|
|
9
|
+
migrateVoiceCallLegacyConfigInput,
|
|
10
|
+
normalizeVoiceCallLegacyConfigInput,
|
|
11
|
+
parseVoiceCallPluginConfig,
|
|
12
|
+
} from "./src/config-compat.js";
|