@openclaw/voice-call 2026.3.13 → 2026.5.2-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.
Files changed (103) hide show
  1. package/README.md +27 -5
  2. package/api.ts +16 -0
  3. package/cli-metadata.ts +10 -0
  4. package/config-api.ts +12 -0
  5. package/index.test.ts +943 -0
  6. package/index.ts +379 -149
  7. package/openclaw.plugin.json +384 -157
  8. package/package.json +35 -5
  9. package/runtime-api.ts +20 -0
  10. package/runtime-entry.ts +1 -0
  11. package/setup-api.ts +47 -0
  12. package/src/allowlist.test.ts +18 -0
  13. package/src/cli.ts +533 -68
  14. package/src/config-compat.test.ts +120 -0
  15. package/src/config-compat.ts +227 -0
  16. package/src/config.test.ts +273 -12
  17. package/src/config.ts +355 -72
  18. package/src/core-bridge.ts +2 -147
  19. package/src/deep-merge.test.ts +40 -0
  20. package/src/gateway-continue-operation.ts +200 -0
  21. package/src/http-headers.ts +6 -3
  22. package/src/manager/context.ts +6 -5
  23. package/src/manager/events.test.ts +243 -19
  24. package/src/manager/events.ts +61 -31
  25. package/src/manager/lifecycle.ts +53 -0
  26. package/src/manager/lookup.test.ts +52 -0
  27. package/src/manager/outbound.test.ts +528 -0
  28. package/src/manager/outbound.ts +163 -57
  29. package/src/manager/store.ts +18 -6
  30. package/src/manager/timers.test.ts +129 -0
  31. package/src/manager/timers.ts +4 -3
  32. package/src/manager/twiml.test.ts +13 -0
  33. package/src/manager/twiml.ts +8 -0
  34. package/src/manager.closed-loop.test.ts +30 -12
  35. package/src/manager.inbound-allowlist.test.ts +77 -10
  36. package/src/manager.notify.test.ts +344 -20
  37. package/src/manager.restore.test.ts +95 -8
  38. package/src/manager.test-harness.ts +8 -6
  39. package/src/manager.ts +79 -5
  40. package/src/media-stream.test.ts +578 -81
  41. package/src/media-stream.ts +235 -54
  42. package/src/providers/base.ts +19 -0
  43. package/src/providers/mock.ts +7 -1
  44. package/src/providers/plivo.test.ts +50 -6
  45. package/src/providers/plivo.ts +14 -6
  46. package/src/providers/shared/call-status.ts +2 -1
  47. package/src/providers/shared/guarded-json-api.test.ts +106 -0
  48. package/src/providers/shared/guarded-json-api.ts +1 -1
  49. package/src/providers/telnyx.test.ts +178 -6
  50. package/src/providers/telnyx.ts +40 -3
  51. package/src/providers/twilio/api.test.ts +145 -0
  52. package/src/providers/twilio/api.ts +67 -16
  53. package/src/providers/twilio/twiml-policy.ts +6 -10
  54. package/src/providers/twilio/webhook.ts +1 -1
  55. package/src/providers/twilio.test.ts +425 -25
  56. package/src/providers/twilio.ts +230 -77
  57. package/src/providers/twilio.types.ts +17 -0
  58. package/src/realtime-defaults.ts +3 -0
  59. package/src/realtime-fast-context.test.ts +88 -0
  60. package/src/realtime-fast-context.ts +165 -0
  61. package/src/realtime-transcription.runtime.ts +4 -0
  62. package/src/realtime-voice.runtime.ts +5 -0
  63. package/src/response-generator.test.ts +321 -0
  64. package/src/response-generator.ts +213 -53
  65. package/src/response-model.test.ts +71 -0
  66. package/src/response-model.ts +23 -0
  67. package/src/runtime.test.ts +429 -0
  68. package/src/runtime.ts +270 -24
  69. package/src/telephony-audio.test.ts +61 -0
  70. package/src/telephony-audio.ts +1 -79
  71. package/src/telephony-tts.test.ts +133 -12
  72. package/src/telephony-tts.ts +155 -2
  73. package/src/test-fixtures.ts +28 -7
  74. package/src/tts-provider-voice.test.ts +34 -0
  75. package/src/tts-provider-voice.ts +21 -0
  76. package/src/tunnel.test.ts +166 -0
  77. package/src/tunnel.ts +1 -1
  78. package/src/types.ts +24 -37
  79. package/src/utils.test.ts +17 -0
  80. package/src/voice-mapping.test.ts +34 -0
  81. package/src/voice-mapping.ts +3 -2
  82. package/src/webhook/realtime-handler.test.ts +598 -0
  83. package/src/webhook/realtime-handler.ts +485 -0
  84. package/src/webhook/stale-call-reaper.test.ts +88 -0
  85. package/src/webhook/stale-call-reaper.ts +5 -0
  86. package/src/webhook/tailscale.test.ts +214 -0
  87. package/src/webhook/tailscale.ts +19 -5
  88. package/src/webhook-exposure.test.ts +33 -0
  89. package/src/webhook-exposure.ts +84 -0
  90. package/src/webhook-security.test.ts +172 -21
  91. package/src/webhook-security.ts +43 -29
  92. package/src/webhook.hangup-once.lifecycle.test.ts +135 -0
  93. package/src/webhook.test.ts +1145 -27
  94. package/src/webhook.ts +523 -102
  95. package/src/webhook.types.ts +5 -0
  96. package/src/websocket-test-support.ts +72 -0
  97. package/tsconfig.json +16 -0
  98. package/CHANGELOG.md +0 -121
  99. package/src/providers/index.ts +0 -10
  100. package/src/providers/stt-openai-realtime.test.ts +0 -42
  101. package/src/providers/stt-openai-realtime.ts +0 -311
  102. package/src/providers/tts-openai.test.ts +0 -43
  103. 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
- mkdir -p ~/.openclaw/extensions
29
- cp -R extensions/voice-call ~/.openclaw/extensions/voice-call
30
- cd ~/.openclaw/extensions/voice-call && pnpm install
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
@@ -39,6 +40,7 @@ Put under `plugins.entries.voice-call.config`:
39
40
  provider: "twilio", // or "telnyx" | "plivo" | "mock"
40
41
  fromNumber: "+15550001234",
41
42
  toNumber: "+15550005678",
43
+ sessionScope: "per-phone", // or "per-call"
42
44
 
43
45
  twilio: {
44
46
  accountSid: "ACxxxxxxxx",
@@ -73,9 +75,20 @@ Put under `plugins.entries.voice-call.config`:
73
75
  defaultMode: "notify", // or "conversation"
74
76
  },
75
77
 
78
+ // Optional response agent workspace. Defaults to "main".
79
+ agentId: "main",
80
+
76
81
  streaming: {
77
82
  enabled: true,
83
+ // optional; if omitted, Voice Call picks the first registered
84
+ // realtime-transcription provider by autoSelectOrder
85
+ provider: "<realtime-transcription-provider-id>",
78
86
  streamPath: "/voice/stream",
87
+ providers: {
88
+ "<realtime-transcription-provider-id>": {
89
+ // provider-owned options
90
+ },
91
+ },
79
92
  preStartTimeoutMs: 5000,
80
93
  maxPendingConnections: 32,
81
94
  maxPendingConnectionsPerIp: 4,
@@ -89,7 +102,10 @@ Notes:
89
102
  - Twilio/Telnyx/Plivo require a **publicly reachable** webhook URL.
90
103
  - `mock` is a local dev provider (no network calls).
91
104
  - Telnyx requires `telnyx.publicKey` (or `TELNYX_PUBLIC_KEY`) unless `skipSignatureVerification` is true.
105
+ - If older configs still use `provider: "log"`, `twilio.from`, or legacy `streaming.*` OpenAI keys, run `openclaw doctor --fix` to rewrite them.
92
106
  - advanced webhook, streaming, and tunnel notes: `https://docs.openclaw.ai/plugins/voice-call`
107
+ - `responseModel` is optional. When unset, voice responses use the runtime default model.
108
+ - `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.
93
109
 
94
110
  ## Stale call reaper
95
111
 
@@ -98,7 +114,7 @@ See the plugin docs for recommended ranges and production examples:
98
114
 
99
115
  ## TTS for calls
100
116
 
101
- Voice Call uses the core `messages.tts` configuration (OpenAI or ElevenLabs) for
117
+ Voice Call uses the core `messages.tts` configuration for
102
118
  streaming speech on calls. Override examples and provider caveats live here:
103
119
  `https://docs.openclaw.ai/plugins/voice-call#tts-for-calls`
104
120
 
@@ -109,6 +125,7 @@ openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"
109
125
  openclaw voicecall continue --call-id <id> --message "Any questions?"
110
126
  openclaw voicecall speak --call-id <id> --message "One moment"
111
127
  openclaw voicecall end --call-id <id>
128
+ openclaw voicecall status --json
112
129
  openclaw voicecall status --call-id <id>
113
130
  openclaw voicecall tail
114
131
  openclaw voicecall expose --mode funnel
@@ -140,4 +157,9 @@ Actions:
140
157
  - Adds replay protection for Twilio and Plivo webhooks (valid duplicate callbacks are ignored safely).
141
158
  - Twilio speech turns include a per-turn token so stale/replayed callbacks cannot complete a newer turn.
142
159
  - `responseModel` / `responseSystemPrompt` control AI auto-responses.
143
- - Media streaming requires `ws` and OpenAI Realtime API key.
160
+ - Voice-call auto-responses enforce a spoken JSON contract (`{"spoken":"..."}`) and filter reasoning/meta output before playback.
161
+ - While a Twilio stream is active, playback does not fall back to TwiML `<Say>`; stream-TTS failures fail the playback request.
162
+ - Outbound conversation calls suppress barge-in only while the initial greeting is actively speaking, then re-enable normal interruption.
163
+ - Twilio stream disconnect auto-end uses a short grace window so quick reconnects do not end the call.
164
+ - Realtime provider selection is generic. Configure `streaming.provider` / `realtime.provider` and put provider-owned options under `providers.<id>`.
165
+ - 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";
@@ -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";