chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
92593b5ff5
commit
876be2fbf6
File diff suppressed because it is too large
Load Diff
@ -1,45 +1,39 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想从 OpenClaw 发起外呼语音通话
|
||||
- 你想从 OpenClaw 发起一通外拨语音通话
|
||||
- 你正在配置或开发语音通话插件
|
||||
- 你需要电话场景下的实时语音或流式转录
|
||||
- 你需要在电话系统中使用实时语音或流式转写
|
||||
sidebarTitle: Voice call
|
||||
summary: 通过 Twilio、Telnyx 或 Plivo 拨打外呼语音电话并接听呼入语音电话,并可选择启用实时语音和流式转录
|
||||
summary: 通过 Twilio、Telnyx 或 Plivo 发起外呼语音通话并接听来电,可选择启用实时语音和流式转写
|
||||
title: 语音通话插件
|
||||
x-i18n:
|
||||
generated_at: "2026-05-01T05:39:45Z"
|
||||
generated_at: "2026-05-01T05:59:30Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 08690f9f27de8a3d4d2c6056cd08edcc42f60f0592272a464c07cb1dc7fee26e
|
||||
source_hash: ce208e4c23e6ac6f844dce23a7e6a565b4deb1f32b8018aae7f56ea196d5245c
|
||||
source_path: plugins/voice-call.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
通过插件为 OpenClaw 提供语音通话。支持出站通知、
|
||||
多轮对话、全双工实时语音、流式转写,
|
||||
以及带 allowlist 策略的入站通话。
|
||||
通过插件为 OpenClaw 提供语音通话。支持出站通知、多轮对话、全双工实时语音、流式转写,以及带允许列表策略的呼入通话。
|
||||
|
||||
**当前提供商:** `twilio`(Programmable Voice + Media Streams),
|
||||
`telnyx`(Call Control v2),`plivo`(Voice API + XML transfer + GetInput
|
||||
speech),`mock`(开发/无网络)。
|
||||
**当前提供商:** `twilio`(Programmable Voice + Media Streams)、`telnyx`(Call Control v2)、`plivo`(Voice API + XML transfer + GetInput speech)、`mock`(开发/无网络)。
|
||||
|
||||
<Note>
|
||||
Voice Call 插件在 **Gateway 网关进程内** 运行。如果你使用
|
||||
远程 Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件,
|
||||
然后重启 Gateway 网关以加载它。
|
||||
Voice Call 插件在 **Gateway 网关进程内部**运行。如果你使用远程 Gateway 网关,请在运行 Gateway 网关的机器上安装并配置该插件,然后重启 Gateway 网关以加载它。
|
||||
</Note>
|
||||
|
||||
## 快速开始
|
||||
|
||||
<Steps>
|
||||
<Step title="Install the plugin">
|
||||
<Step title="安装插件">
|
||||
<Tabs>
|
||||
<Tab title="From npm">
|
||||
<Tab title="从 npm 安装">
|
||||
```bash
|
||||
openclaw plugins install @openclaw/voice-call
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="From a local folder (dev)">
|
||||
<Tab title="从本地文件夹安装(开发)">
|
||||
```bash
|
||||
PLUGIN_SRC=./path/to/local/voice-call-plugin
|
||||
openclaw plugins install "$PLUGIN_SRC"
|
||||
@ -48,37 +42,29 @@ Voice Call 插件在 **Gateway 网关进程内** 运行。如果你使用
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
如果 npm 报告 OpenClaw 拥有的软件包已弃用,该软件包版本
|
||||
来自较旧的外部软件包发布线;请使用当前打包的 OpenClaw
|
||||
构建,或在较新的 npm 软件包发布前使用本地文件夹路径。
|
||||
如果 npm 报告 OpenClaw 拥有的软件包已弃用,则该软件包版本来自较旧的外部软件包发布线;请使用当前打包的 OpenClaw 构建,或在发布更新的 npm 软件包之前使用本地文件夹路径。
|
||||
|
||||
之后重启 Gateway 网关,以便插件加载。
|
||||
之后重启 Gateway 网关,以便加载插件。
|
||||
|
||||
</Step>
|
||||
<Step title="Configure provider and webhook">
|
||||
在 `plugins.entries.voice-call.config` 下设置配置(完整结构见下方
|
||||
[配置](#configuration))。至少需要:
|
||||
`provider`、提供商凭证、`fromNumber`,以及可公开访问的 webhook URL。
|
||||
<Step title="配置提供商和 webhook">
|
||||
在 `plugins.entries.voice-call.config` 下设置配置(完整结构见下方[配置](#configuration))。至少需要:`provider`、提供商凭证、`fromNumber`,以及可公开访问的 webhook URL。
|
||||
</Step>
|
||||
<Step title="Verify setup">
|
||||
<Step title="验证设置">
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
```
|
||||
|
||||
默认输出适合在聊天日志和终端中阅读。它会检查
|
||||
插件启用状态、提供商凭证、webhook 暴露情况,以及是否
|
||||
只有一种音频模式(`streaming` 或 `realtime`)处于活动状态。脚本可使用
|
||||
`--json`。
|
||||
默认输出可在聊天日志和终端中阅读。它会检查插件启用状态、提供商凭证、webhook 暴露情况,以及是否只有一种音频模式(`streaming` 或 `realtime`)处于活动状态。脚本请使用 `--json`。
|
||||
|
||||
</Step>
|
||||
<Step title="Smoke test">
|
||||
<Step title="冒烟测试">
|
||||
```bash
|
||||
openclaw voicecall smoke
|
||||
openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
两者默认都是 dry run。添加 `--yes` 才会实际发起一次简短的
|
||||
出站通知通话:
|
||||
默认情况下两者都是试运行。添加 `--yes` 可实际发起一次简短的出站通知通话:
|
||||
|
||||
```bash
|
||||
openclaw voicecall smoke --to "+15555550123" --yes
|
||||
@ -88,21 +74,15 @@ Voice Call 插件在 **Gateway 网关进程内** 运行。如果你使用
|
||||
</Steps>
|
||||
|
||||
<Warning>
|
||||
对于 Twilio、Telnyx 和 Plivo,设置必须解析为 **公共 webhook URL**。
|
||||
如果 `publicUrl`、隧道 URL、Tailscale URL 或 serve fallback
|
||||
解析为 loopback 或专用网络空间,设置会失败,而不是
|
||||
启动无法接收运营商 webhook 的提供商。
|
||||
对于 Twilio、Telnyx 和 Plivo,设置必须解析到一个**公共 webhook URL**。如果 `publicUrl`、隧道 URL、Tailscale URL 或 serve 回退解析到 loopback 或私有网络空间,设置会失败,而不是启动一个无法接收运营商 webhook 的提供商。
|
||||
</Warning>
|
||||
|
||||
## 配置
|
||||
|
||||
如果 `enabled: true` 但所选提供商缺少凭证,
|
||||
Gateway 网关启动时会记录一条设置未完成警告,其中包含缺失键名,
|
||||
并跳过启动运行时。命令、RPC 调用和智能体工具在使用时仍会
|
||||
返回确切缺失的提供商配置。
|
||||
如果 `enabled: true` 但所选提供商缺少凭证,Gateway 网关启动时会记录 setup-incomplete 警告,并列出缺少的键名,同时跳过运行时启动。命令、RPC 调用和智能体工具在使用时仍会返回确切缺失的提供商配置。
|
||||
|
||||
<Note>
|
||||
语音通话凭证支持 SecretRef。`plugins.entries.voice-call.config.twilio.authToken` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 界面解析;见 [SecretRef 凭证界面](/zh-CN/reference/secretref-credential-surface)。
|
||||
Voice-call 凭证接受 SecretRef。`plugins.entries.voice-call.config.twilio.authToken` 和 `plugins.entries.voice-call.config.tts.providers.*.apiKey` 会通过标准 SecretRef 表面解析;参见 [SecretRef 凭证表面](/zh-CN/reference/secretref-credential-surface)。
|
||||
</Note>
|
||||
|
||||
```json5
|
||||
@ -163,31 +143,27 @@ Gateway 网关启动时会记录一条设置未完成警告,其中包含缺失
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Provider exposure and security notes">
|
||||
- Twilio、Telnyx 和 Plivo 都需要一个 **可公开访问** 的 webhook URL。
|
||||
- `mock` 是本地开发提供商(不发起网络调用)。
|
||||
<Accordion title="提供商暴露和安全说明">
|
||||
- Twilio、Telnyx 和 Plivo 都需要一个**可公开访问**的 webhook URL。
|
||||
- `mock` 是本地开发提供商(无网络调用)。
|
||||
- Telnyx 需要 `telnyx.publicKey`(或 `TELNYX_PUBLIC_KEY`),除非 `skipSignatureVerification` 为 true。
|
||||
- `skipSignatureVerification` 仅用于本地测试。
|
||||
- 在 ngrok 免费层上,将 `publicUrl` 设置为确切的 ngrok URL;始终会强制执行签名验证。
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅当 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,才允许签名无效的 Twilio webhook。仅限本地开发。
|
||||
- 在 ngrok 免费层,将 `publicUrl` 设置为确切的 ngrok URL;始终强制执行签名验证。
|
||||
- `tunnel.allowNgrokFreeTierLoopbackBypass: true` 仅在 `tunnel.provider="ngrok"` 且 `serve.bind` 为 loopback(ngrok 本地代理)时,允许带有无效签名的 Twilio webhook。仅限本地开发。
|
||||
- Ngrok 免费层 URL 可能变化或添加插页行为;如果 `publicUrl` 偏移,Twilio 签名会失败。生产环境:优先使用稳定域名或 Tailscale funnel。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Streaming connection caps">
|
||||
- `streaming.preStartTimeoutMs` 会关闭从未发送有效 `start` 帧的套接字。
|
||||
- `streaming.maxPendingConnections` 限制未认证 pre-start 套接字总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未认证 pre-start 套接字数。
|
||||
- `streaming.maxConnections` 限制打开的媒体流套接字总数(pending + active)。
|
||||
<Accordion title="流式连接上限">
|
||||
- `streaming.preStartTimeoutMs` 会关闭从未发送有效 `start` 帧的 socket。
|
||||
- `streaming.maxPendingConnections` 限制未认证的 pre-start socket 总数。
|
||||
- `streaming.maxPendingConnectionsPerIp` 限制每个源 IP 的未认证 pre-start socket 数量。
|
||||
- `streaming.maxConnections` 限制打开的媒体流 socket 总数(pending + active)。
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Legacy config migrations">
|
||||
使用 `provider: "log"`、`twilio.from` 或旧版
|
||||
`streaming.*` OpenAI 键的旧配置会由 `openclaw doctor --fix` 重写。
|
||||
运行时 fallback 目前仍接受旧的 voice-call 键,但
|
||||
重写路径是 `openclaw doctor --fix`,兼容 shim 是
|
||||
临时的。
|
||||
<Accordion title="旧版配置迁移">
|
||||
使用 `provider: "log"`、`twilio.from` 或旧版 `streaming.*` OpenAI 键的较旧配置会由 `openclaw doctor --fix` 重写。目前运行时回退仍接受旧的 voice-call 键,但重写路径是 `openclaw doctor --fix`,且兼容 shim 是临时的。
|
||||
|
||||
自动迁移的 streaming 键:
|
||||
自动迁移的流式键:
|
||||
|
||||
- `streaming.sttProvider` → `streaming.provider`
|
||||
- `streaming.openaiApiKey` → `streaming.providers.openai.apiKey`
|
||||
@ -200,42 +176,37 @@ Gateway 网关启动时会记录一条设置未完成警告,其中包含缺失
|
||||
|
||||
## 实时语音对话
|
||||
|
||||
`realtime` 为实时通话音频选择一个全双工实时语音提供商。
|
||||
它与 `streaming` 分开,后者只会将音频转发给
|
||||
实时转写提供商。
|
||||
`realtime` 为实时通话音频选择全双工实时语音提供商。它与 `streaming` 分离,后者只会将音频转发给实时转写提供商。
|
||||
|
||||
<Warning>
|
||||
`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次通话请选择一种
|
||||
音频模式。
|
||||
`realtime.enabled` 不能与 `streaming.enabled` 组合使用。每次通话只能选择一种音频模式。
|
||||
</Warning>
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
- Twilio Media Streams 支持 `realtime.enabled`。
|
||||
- `realtime.provider` 是可选的。如果未设置,Voice Call 会使用第一个已注册的实时语音提供商。
|
||||
- 内置实时语音提供商:Google Gemini Live(`google`)和 OpenAI(`openai`),由它们的提供商插件注册。
|
||||
- 内置实时语音提供商:Google Gemini Live(`google`)和 OpenAI(`openai`),由各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `realtime.providers.<providerId>` 下。
|
||||
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者请求更深入的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
|
||||
- 如果 `realtime.provider` 指向未注册的提供商,或根本没有注册任何实时语音提供商,Voice Call 会记录警告并跳过实时媒体,而不是让整个插件失败。
|
||||
- consult 会话键会在可用时复用现有语音会话,然后回退到主叫/被叫电话号码,以便后续 consult 调用在通话期间保持上下文。
|
||||
- Voice Call 默认暴露共享的 `openclaw_agent_consult` 实时工具。当来电者要求更深入的推理、当前信息或普通 OpenClaw 工具时,实时模型可以调用它。
|
||||
- 如果 `realtime.provider` 指向未注册的提供商,或者根本没有注册实时语音提供商,Voice Call 会记录警告并跳过实时媒体,而不是让整个插件失败。
|
||||
- 咨询会话键会在可用时复用现有语音会话,然后回退到主叫/被叫电话号码,以便跟进咨询调用在通话期间保留上下文。
|
||||
|
||||
### 工具策略
|
||||
|
||||
`realtime.toolPolicy` 控制 consult 运行:
|
||||
`realtime.toolPolicy` 控制咨询运行:
|
||||
|
||||
| 策略 | 行为 |
|
||||
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `safe-read-only` | 暴露 consult 工具,并将常规智能体限制为 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。 |
|
||||
| `owner` | 暴露 consult 工具,并允许常规智能体使用普通智能体工具策略。 |
|
||||
| `none` | 不暴露 consult 工具。自定义 `realtime.tools` 仍会传递给实时提供商。 |
|
||||
| `safe-read-only` | 暴露咨询工具,并将常规智能体限制为 `read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和 `memory_get`。 |
|
||||
| `owner` | 暴露咨询工具,并让常规智能体使用正常的智能体工具策略。 |
|
||||
| `none` | 不暴露咨询工具。自定义 `realtime.tools` 仍会传递给实时提供商。 |
|
||||
|
||||
### 实时提供商示例
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Google Gemini Live">
|
||||
默认值:API key 来自 `realtime.providers.google.apiKey`、
|
||||
`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`;模型
|
||||
`gemini-2.5-flash-native-audio-preview-12-2025`;语音 `Kore`。
|
||||
默认值:API key 来自 `realtime.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_GENERATIVE_AI_API_KEY`;模型 `gemini-2.5-flash-native-audio-preview-12-2025`;语音 `Kore`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -290,28 +261,25 @@ Gateway 网关启动时会记录一条设置未完成警告,其中包含缺失
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
有关提供商专用的实时语音选项,请参阅 [Google 提供商](/zh-CN/providers/google) 和
|
||||
[OpenAI provider](/zh-CN/providers/openai)。
|
||||
有关提供商特定的实时语音选项,请参见 [Google 提供商](/zh-CN/providers/google) 和 [OpenAI provider](/zh-CN/providers/openai)。
|
||||
|
||||
## 流式转写
|
||||
|
||||
`streaming` 为实时通话音频选择一个实时转写提供商。
|
||||
`streaming` 为实时通话音频选择实时转写提供商。
|
||||
|
||||
当前运行时行为:
|
||||
|
||||
- `streaming.provider` 是可选的。如果未设置,Voice Call 会使用第一个已注册的实时转写提供商。
|
||||
- 内置实时转写提供商:Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由它们的提供商插件注册。
|
||||
- 内置实时转写提供商:Deepgram(`deepgram`)、ElevenLabs(`elevenlabs`)、Mistral(`mistral`)、OpenAI(`openai`)和 xAI(`xai`),由各自的提供商插件注册。
|
||||
- 提供商拥有的原始配置位于 `streaming.providers.<providerId>` 下。
|
||||
- Twilio 发送已接受的流 `start` 消息后,Voice Call 会立即注册该流,在提供商连接期间通过转写提供商排队入站媒体,并且仅在实时转写准备就绪后开始初始问候。
|
||||
- 如果 `streaming.provider` 指向未注册的提供商,或没有任何提供商注册,Voice Call 会记录警告并跳过媒体流式传输,而不是让整个插件失败。
|
||||
- Twilio 发送已接受的流 `start` 消息后,Voice Call 会立即注册该流,在提供商连接期间通过转写提供商排队处理入站媒体,并且仅在实时转写就绪后启动初始问候语。
|
||||
- 如果 `streaming.provider` 指向未注册的提供商,或者没有注册任何提供商,Voice Call 会记录警告并跳过媒体流式传输,而不是让整个插件失败。
|
||||
|
||||
### 流式提供商示例
|
||||
|
||||
<Tabs>
|
||||
<Tab title="OpenAI">
|
||||
默认值:API key `streaming.providers.openai.apiKey` 或
|
||||
`OPENAI_API_KEY`;模型 `gpt-4o-transcribe`;`silenceDurationMs: 800`;
|
||||
`vadThreshold: 0.5`。
|
||||
默认值:API key `streaming.providers.openai.apiKey` 或 `OPENAI_API_KEY`;模型 `gpt-4o-transcribe`;`silenceDurationMs: 800`;`vadThreshold: 0.5`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -373,9 +341,10 @@ Gateway 网关启动时会记录一条设置未完成警告,其中包含缺失
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 通话的 TTS
|
||||
## 调用的 TTS
|
||||
|
||||
Voice Call 使用核心 `messages.tts` 配置来处理通话中的流式语音。你可以在插件配置下用**相同结构**覆盖它 — 它会与 `messages.tts` 深度合并。
|
||||
Voice Call 使用核心 `messages.tts` 配置为调用提供流式
|
||||
语音。你可以在插件配置下用**相同结构**覆盖它,它会与 `messages.tts` 深度合并。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -392,16 +361,17 @@ Voice Call 使用核心 `messages.tts` 配置来处理通话中的流式语音
|
||||
```
|
||||
|
||||
<Warning>
|
||||
**语音通话会忽略 Microsoft speech。** 电话音频需要 PCM;当前 Microsoft 传输不公开电话 PCM 输出。
|
||||
**Microsoft speech 会在语音调用中被忽略。** 电话音频需要 PCM;
|
||||
当前 Microsoft 传输不暴露电话 PCM 输出。
|
||||
</Warning>
|
||||
|
||||
行为说明:
|
||||
|
||||
- 插件配置中的旧版 `tts.<provider>` 键(`openai`、`elevenlabs`、`microsoft`、`edge`)会由 `openclaw doctor --fix` 修复;提交的配置应使用 `tts.providers.<provider>`。
|
||||
- 启用 Twilio 媒体流式传输时会使用核心 TTS;否则通话会回退到提供商原生语音。
|
||||
- 如果 Twilio 媒体流已经处于活动状态,Voice Call 不会回退到 TwiML `<Say>`。如果在该状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。
|
||||
- 当电话 TTS 回退到次级提供商时,Voice Call 会记录一条带有提供商链(`from`、`to`、`attempts`)的警告,便于调试。
|
||||
- 当 Twilio 插话或流拆除清空待处理 TTS 队列时,排队的播放请求会完成结算,而不是让调用方在等待播放完成时挂起。
|
||||
- 启用 Twilio 媒体流时会使用核心 TTS;否则调用会回退到提供商原生语音。
|
||||
- 如果 Twilio 媒体流已处于活动状态,Voice Call 不会回退到 TwiML `<Say>`。如果在该状态下电话 TTS 不可用,播放请求会失败,而不是混用两条播放路径。
|
||||
- 当电话 TTS 回退到次级提供商时,Voice Call 会记录一条包含提供商链(`from`、`to`、`attempts`)的警告,便于调试。
|
||||
- 当 Twilio 打断或流拆除清空待处理 TTS 队列时,已排队的播放请求会完成结算,而不是让调用方一直等待播放完成。
|
||||
|
||||
### TTS 示例
|
||||
|
||||
@ -468,9 +438,9 @@ Voice Call 使用核心 `messages.tts` 配置来处理通话中的流式语音
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 来电
|
||||
## 入站调用
|
||||
|
||||
来电策略默认值为 `disabled`。要启用来电,请设置:
|
||||
入站策略默认为 `disabled`。要启用入站调用,请设置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -481,52 +451,63 @@ Voice Call 使用核心 `messages.tts` 配置来处理通话中的流式语音
|
||||
```
|
||||
|
||||
<Warning>
|
||||
`inboundPolicy: "allowlist"` 是低保障的来电号码筛选。该插件会规范化提供商提供的 `From` 值,并将其与 `allowFrom` 比较。Webhook 验证会认证提供商投递和负载完整性,但它**不能**证明 PSTN/VoIP 主叫号码所有权。应将 `allowFrom` 视为来电号码过滤,而不是强主叫身份验证。
|
||||
`inboundPolicy: "allowlist"` 是低保证级别的来电号码筛选。
|
||||
插件会规范化提供商提供的 `From` 值,并将其与
|
||||
`allowFrom` 比较。Webhook 验证会认证提供商投递和
|
||||
载荷完整性,但它**不能**证明 PSTN/VoIP 来电号码
|
||||
所有权。请将 `allowFrom` 视为来电号码过滤,而不是强来电方
|
||||
身份。
|
||||
</Warning>
|
||||
|
||||
自动响应使用智能体系统。使用 `responseModel`、`responseSystemPrompt` 和 `responseTimeoutMs` 调整。
|
||||
自动响应使用智能体系统。可通过 `responseModel`、
|
||||
`responseSystemPrompt` 和 `responseTimeoutMs` 调整。
|
||||
|
||||
### 语音输出契约
|
||||
|
||||
对于自动响应,Voice Call 会将严格的语音输出契约附加到系统提示词:
|
||||
对于自动响应,Voice Call 会向 system prompt 追加严格的语音输出契约:
|
||||
|
||||
```text
|
||||
{"spoken":"..."}
|
||||
```
|
||||
|
||||
Voice Call 会防御性地提取语音文本:
|
||||
Voice Call 会以防御性方式提取语音文本:
|
||||
|
||||
- 忽略标记为推理/错误内容的负载。
|
||||
- 忽略标记为推理/错误内容的载荷。
|
||||
- 解析直接 JSON、围栏 JSON 或内联 `"spoken"` 键。
|
||||
- 回退到纯文本,并移除可能的规划/元信息开头段落。
|
||||
- 回退到纯文本,并移除看起来像规划/元信息引入的段落。
|
||||
|
||||
这会让语音播放聚焦于面向调用方的文本,并避免将规划文本泄漏到音频中。
|
||||
这会让语音播放聚焦于面向来电方的文本,并避免
|
||||
将规划文本泄漏到音频中。
|
||||
|
||||
### 对话启动行为
|
||||
|
||||
对于出站 `conversation` 通话,首条消息处理与实时播放状态绑定:
|
||||
对于出站 `conversation` 调用,首条消息处理与实时
|
||||
播放状态绑定:
|
||||
|
||||
- 仅当初始问候正在主动播放时,才会抑制插话队列清空和自动响应。
|
||||
- 如果初始播放失败,通话会返回 `listening`,且初始消息仍保留在队列中以便重试。
|
||||
- Twilio 流式传输的初始播放会在流连接时开始,不会额外延迟。
|
||||
- 插话会中止活动播放,并清除已排队但尚未播放的 Twilio TTS 条目。清除的条目会解析为已跳过,因此后续响应逻辑可以继续,而无需等待永远不会播放的音频。
|
||||
- 实时语音对话使用实时流自己的开场回合。Voice Call **不会**为该初始消息发布旧版 `<Say>` TwiML 更新,因此出站 `<Connect><Stream>` 会话会保持连接。
|
||||
- 仅当初始问候正在主动播放时,才会抑制打断队列清空和自动响应。
|
||||
- 如果初始播放失败,调用会返回 `listening`,初始消息会保持排队以便重试。
|
||||
- Twilio 流式传输的初始播放会在流连接时启动,不会额外延迟。
|
||||
- 打断会中止活动播放,并清空已排队但尚未播放的 Twilio TTS 条目。被清空的条目会解析为已跳过,因此后续响应逻辑可以继续,而无需等待永远不会播放的音频。
|
||||
- Realtime 语音对话使用 realtime 流自己的开场轮次。Voice Call **不会**为该初始消息发布旧版 `<Say>` TwiML 更新,因此出站 `<Connect><Stream>` 会话会保持附着。
|
||||
|
||||
### Twilio 流断开宽限期
|
||||
|
||||
当 Twilio 媒体流断开时,Voice Call 会等待 **2000 ms** 后再自动结束通话:
|
||||
当 Twilio 媒体流断开时,Voice Call 会等待 **2000 ms** 后再
|
||||
自动结束调用:
|
||||
|
||||
- 如果流在该窗口内重新连接,则取消自动结束。
|
||||
- 如果宽限期后没有流重新注册,则结束通话,防止活动通话卡住。
|
||||
- 如果流在该窗口内重新连接,自动结束会被取消。
|
||||
- 如果宽限期后没有流重新注册,调用会被结束,以防止活动调用卡住。
|
||||
|
||||
## 过期通话清理器
|
||||
## 过期调用清理器
|
||||
|
||||
使用 `staleCallReaperSeconds` 结束从未收到终止 webhook 的通话(例如从未完成的 notify 模式通话)。默认值为 `0`(禁用)。
|
||||
使用 `staleCallReaperSeconds` 结束从未收到终止
|
||||
webhook 的调用(例如永不完成的通知模式调用)。默认值
|
||||
为 `0`(禁用)。
|
||||
|
||||
建议范围:
|
||||
推荐范围:
|
||||
|
||||
- **生产环境:** 对于通知式流程,使用 `120`–`300` 秒。
|
||||
- 保持该值**高于 `maxDurationSeconds`**,以便正常通话能够完成。一个良好的起点是 `maxDurationSeconds + 30–60` 秒。
|
||||
- **生产环境:**用于通知式流程时设为 `120`–`300` 秒。
|
||||
- 将此值保持为**高于 `maxDurationSeconds`**,这样正常呼叫才能完成。一个合适的起点是 `maxDurationSeconds + 30–60` 秒。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -545,26 +526,26 @@ Voice Call 会防御性地提取语音文本:
|
||||
|
||||
## Webhook 安全
|
||||
|
||||
当代理或隧道位于 Gateway 网关前面时,该插件会重建用于签名验证的公开 URL。这些选项控制信任哪些转发标头:
|
||||
当代理或隧道位于 Gateway 网关前面时,插件会重建用于签名验证的公共 URL。这些选项控制信任哪些转发标头:
|
||||
|
||||
<ParamField path="webhookSecurity.allowedHosts" type="string[]">
|
||||
允许列表中的转发标头主机。
|
||||
允许来自转发标头的主机列表。
|
||||
</ParamField>
|
||||
<ParamField path="webhookSecurity.trustForwardingHeaders" type="boolean">
|
||||
在没有允许列表的情况下信任转发标头。
|
||||
不使用允许列表也信任转发标头。
|
||||
</ParamField>
|
||||
<ParamField path="webhookSecurity.trustedProxyIPs" type="string[]">
|
||||
仅当请求远程 IP 与列表匹配时,才信任转发标头。
|
||||
仅当请求远端 IP 匹配列表时才信任转发标头。
|
||||
</ParamField>
|
||||
|
||||
额外保护:
|
||||
|
||||
- Twilio 和 Plivo 已启用 webhook **重放保护**。重放的有效 webhook 请求会被确认,但会跳过副作用。
|
||||
- Twilio 对话回合在 `<Gather>` 回调中包含每回合 token,因此过期/重放的语音回调无法满足较新的待处理转录回合。
|
||||
- 当缺少提供商所需的签名标头时,未认证的 webhook 请求会在读取正文前被拒绝。
|
||||
- voice-call webhook 使用共享的预认证正文配置(64 KB / 5 秒),并在签名验证前施加按 IP 统计的进行中请求上限。
|
||||
- Twilio 和 Plivo 已启用 Webhook **重放保护**。重放的有效 Webhook 请求会被确认,但会跳过副作用。
|
||||
- Twilio 对话轮次会在 `<Gather>` 回调中包含每轮 token,因此过期或重放的语音回调无法满足新的待处理转录轮次。
|
||||
- 当缺少提供商要求的签名标头时,未经认证的 Webhook 请求会在读取正文前被拒绝。
|
||||
- voice-call Webhook 使用共享的预认证正文配置(64 KB / 5 秒),并在签名验证前应用按 IP 统计的进行中请求上限。
|
||||
|
||||
使用稳定公开主机的示例:
|
||||
使用稳定公共主机的示例:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -598,9 +579,9 @@ openclaw voicecall latency # summarize turn latency from lo
|
||||
openclaw voicecall expose --mode funnel
|
||||
```
|
||||
|
||||
当 Gateway 网关已在运行时,操作性 `voicecall` 命令会委托给 Gateway 网关拥有的 voice-call 运行时,因此 CLI 不会绑定第二个 webhook 服务器。如果无法访问 Gateway 网关,这些命令会回退到独立 CLI 运行时。
|
||||
当 Gateway 网关已在运行时,操作型 `voicecall` 命令会委托给 Gateway 网关拥有的 voice-call 运行时,因此 CLI 不会绑定第二个 Webhook 服务器。如果无法连接到 Gateway 网关,这些命令会回退到独立的 CLI 运行时。
|
||||
|
||||
`latency` 从默认 voice-call 存储路径读取 `calls.jsonl`。使用 `--file <path>` 指向不同日志,并使用 `--last <n>` 将分析限制为最后 N 条记录(默认 200)。输出包括回合延迟和听取等待时间的 p50/p90/p99。
|
||||
`latency` 会从默认 voice-call 存储路径读取 `calls.jsonl`。使用 `--file <path>` 指向不同日志,使用 `--last <n>` 将分析限制为最后 N 条记录(默认 200)。输出包含轮次延迟和监听等待时间的 p50/p90/p99。
|
||||
|
||||
## 智能体工具
|
||||
|
||||
@ -615,7 +596,7 @@ openclaw voicecall expose --mode funnel
|
||||
| `end_call` | `callId` |
|
||||
| `get_status` | `callId` |
|
||||
|
||||
此仓库在 `skills/voice-call/SKILL.md` 提供匹配的 skill 文档。
|
||||
此仓库在 `skills/voice-call/SKILL.md` 提供了匹配的 skill 文档。
|
||||
|
||||
## Gateway 网关 RPC
|
||||
|
||||
@ -628,8 +609,124 @@ openclaw voicecall expose --mode funnel
|
||||
| `voicecall.end` | `callId` |
|
||||
| `voicecall.status` | `callId` |
|
||||
|
||||
## 相关内容
|
||||
## 故障排除
|
||||
|
||||
- [Talk 模式](/zh-CN/nodes/talk)
|
||||
### 设置无法暴露 Webhook
|
||||
|
||||
请从运行 Gateway 网关的同一环境中运行设置:
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
openclaw voicecall setup --json
|
||||
```
|
||||
|
||||
对于 `twilio`、`telnyx` 和 `plivo`,`webhook-exposure` 必须为绿色。已配置的 `publicUrl` 如果指向本地或私有网络空间,仍会失败,因为运营商无法回调这些地址。不要将 `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` 或 `fd00::/8` 用作 `publicUrl`。
|
||||
|
||||
使用一种公共暴露路径:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
"voice-call": {
|
||||
config: {
|
||||
publicUrl: "https://voice.example.com/voice/webhook",
|
||||
// or
|
||||
tunnel: { provider: "ngrok" },
|
||||
// or
|
||||
tailscale: { mode: "funnel", path: "/voice/webhook" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
更改配置后,重启或重新加载 Gateway 网关,然后运行:
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
openclaw voicecall smoke
|
||||
```
|
||||
|
||||
除非你传入 `--yes`,否则 `voicecall smoke` 是一次演练。
|
||||
|
||||
### 提供商凭证失败
|
||||
|
||||
检查所选提供商和必需的凭证字段:
|
||||
|
||||
- Twilio:`twilio.accountSid`、`twilio.authToken` 和 `fromNumber`,或 `TWILIO_ACCOUNT_SID`、`TWILIO_AUTH_TOKEN` 和 `TWILIO_FROM_NUMBER`。
|
||||
- Telnyx:`telnyx.apiKey`、`telnyx.connectionId`、`telnyx.publicKey` 和 `fromNumber`。
|
||||
- Plivo:`plivo.authId`、`plivo.authToken` 和 `fromNumber`。
|
||||
|
||||
凭证必须存在于 Gateway 网关主机上。编辑本地 shell 配置文件不会影响已经运行的 Gateway 网关,直到它重启或重新加载其环境。
|
||||
|
||||
### 调用开始但提供商 webhooks 未到达
|
||||
|
||||
确认提供商控制台指向确切的公开 webhook URL:
|
||||
|
||||
```text
|
||||
https://voice.example.com/voice/webhook
|
||||
```
|
||||
|
||||
然后检查运行时状态:
|
||||
|
||||
```bash
|
||||
openclaw voicecall status --call-id <id>
|
||||
openclaw voicecall tail
|
||||
```
|
||||
|
||||
常见原因:
|
||||
|
||||
- `publicUrl` 指向的路径与 `serve.path` 不同。
|
||||
- 隧道 URL 在 Gateway 网关启动后发生了变化。
|
||||
- 代理转发了请求,但剥离或重写了 host/proto 标头。
|
||||
- 防火墙或 DNS 将公开主机名路由到了 Gateway 网关以外的位置。
|
||||
- Gateway 网关重启时未启用 Voice Call 插件。
|
||||
|
||||
当 Gateway 网关前面有反向代理或隧道时,将 `webhookSecurity.allowedHosts` 设置为公开主机名,或对已知代理地址使用 `webhookSecurity.trustedProxyIPs`。仅当代理边界由你控制时,才使用 `webhookSecurity.trustForwardingHeaders`。
|
||||
|
||||
### 签名验证失败
|
||||
|
||||
提供商签名会根据 OpenClaw 从传入请求重建的公开 URL 进行检查。如果签名失败:
|
||||
|
||||
- 确认提供商 webhook URL 与 `publicUrl` 完全匹配,包括 scheme、host 和 path。
|
||||
- 对于 ngrok 免费层级 URL,当隧道主机名变化时更新 `publicUrl`。
|
||||
- 确保代理保留原始 host 和 proto 标头,或配置 `webhookSecurity.allowedHosts`。
|
||||
- 不要在本地测试之外启用 `skipSignatureVerification`。
|
||||
|
||||
### Google Meet Twilio 加入失败
|
||||
|
||||
Google Meet 使用此插件进行 Twilio 拨入加入。首先验证 Voice Call:
|
||||
|
||||
```bash
|
||||
openclaw voicecall setup
|
||||
openclaw voicecall smoke --to "+15555550123"
|
||||
```
|
||||
|
||||
然后显式验证 Google Meet 传输:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet setup --transport twilio
|
||||
```
|
||||
|
||||
如果 Voice Call 状态正常,但 Meet 参与者从未加入,请检查 Meet 拨入号码、PIN 和 `--dtmf-sequence`。电话呼叫可能正常,而会议会拒绝或忽略不正确的 DTMF 序列。
|
||||
|
||||
Google Meet 会静默启动 Voice Call,发送 DTMF,然后让 Voice Call 在 `voiceCall.postDtmfSpeechDelayMs` 之后朗读开场白。如果第一句话在 Meet 允许电话参与者加入之前就被朗读,请在 Google Meet 插件配置中增加该延迟。
|
||||
|
||||
### 实时通话没有语音
|
||||
|
||||
确认只启用了一种音频模式。`realtime.enabled` 和 `streaming.enabled` 不能同时为 true。
|
||||
|
||||
对于实时 Twilio 通话,还要验证:
|
||||
|
||||
- 已加载并注册实时提供商插件。
|
||||
- `realtime.provider` 未设置,或命名了已注册的提供商。
|
||||
- Gateway 网关进程可以使用提供商 API key。
|
||||
- `openclaw voicecall tail` 在初始问候之前显示媒体流已被接受,且实时提供商已就绪。
|
||||
|
||||
## 相关
|
||||
|
||||
- [对话模式](/zh-CN/nodes/talk)
|
||||
- [文本转语音](/zh-CN/tools/tts)
|
||||
- [语音唤醒](/zh-CN/nodes/voicewake)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user