chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
fe8a6f6750
commit
e344ccda27
@ -1,56 +1,57 @@
|
||||
---
|
||||
read_when:
|
||||
- 你希望一个 OpenClaw 智能体加入 Google Meet 通话
|
||||
- 你正在将 Chrome 或 Twilio 配置为 Google Meet 传输方式
|
||||
summary: Google Meet 插件:通过 Chrome 或 Twilio 使用实时语音默认设置加入显式 Meet URL
|
||||
- 你正在将 Chrome、Chrome 节点或 Twilio 配置为 Google Meet 传输方式
|
||||
summary: Google Meet 插件:通过 Chrome 或 Twilio 加入明确的 Meet URL,并使用实时语音默认设置
|
||||
title: Google Meet 插件
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T03:42:24Z"
|
||||
generated_at: "2026-04-24T04:34:46Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 0ff8fa088d162e1d90e7f4cff9e72db485d6777f56086203d70d4c7071d70000
|
||||
source_hash: 5c89587eeab8440b2ded2c352cc73209753fc4697d9fdf44cfe39de9d1d76b3f
|
||||
source_path: plugins/google-meet.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Google Meet(插件)
|
||||
|
||||
为 OpenClaw 提供 Google Meet 参与者支持。
|
||||
适用于 OpenClaw 的 Google Meet 参与者支持。
|
||||
|
||||
该插件按设计是显式的:
|
||||
该插件在设计上是显式的:
|
||||
|
||||
- 它只会加入显式的 `https://meet.google.com/...` URL。
|
||||
- 它只会加入明确的 `https://meet.google.com/...` URL。
|
||||
- `realtime` 语音是默认模式。
|
||||
- 当需要更深入的推理或工具时,实时语音可以回调到完整的 OpenClaw 智能体。
|
||||
- 认证从个人 Google OAuth 或已登录的 Chrome 配置文件开始。
|
||||
- 没有自动同意公告。
|
||||
- 当需要更深入的推理或工具时,实时语音可以回调完整的 OpenClaw 智能体。
|
||||
- 认证起始方式是个人 Google OAuth 或已登录的 Chrome 配置文件。
|
||||
- 不会自动播报同意声明。
|
||||
- 默认的 Chrome 音频后端是 `BlackHole 2ch`。
|
||||
- Chrome 可以在本地运行,也可以在已配对的节点主机上运行。
|
||||
- Twilio 接受拨入号码以及可选的 PIN 或 DTMF 序列。
|
||||
- CLI 命令是 `googlemeet`;`meet` 保留给更广泛的智能体电话会议工作流。
|
||||
- CLI 命令是 `googlemeet`;`meet` 保留给更广泛的智能体电话会议工作流使用。
|
||||
|
||||
## 快速开始
|
||||
|
||||
安装本地音频依赖,并确保 realtime 提供商可以使用 OpenAI:
|
||||
安装本地音频依赖,并确保实时提供商可以使用 OpenAI:
|
||||
|
||||
```bash
|
||||
brew install blackhole-2ch sox
|
||||
export OPENAI_API_KEY=sk-...
|
||||
```
|
||||
|
||||
`blackhole-2ch` 会安装 `BlackHole 2ch` 虚拟音频设备。Homebrew 的安装程序要求重启后 macOS 才会暴露该设备:
|
||||
`blackhole-2ch` 会安装 `BlackHole 2ch` 虚拟音频设备。Homebrew 的安装程序要求重启,macOS 才会显示该设备:
|
||||
|
||||
```bash
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
重启后,验证这两项:
|
||||
重启后,验证这两项都已就绪:
|
||||
|
||||
```bash
|
||||
system_profiler SPAudioDataType | grep -i BlackHole
|
||||
command -v rec play
|
||||
```
|
||||
|
||||
启用插件:
|
||||
启用该插件:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -86,32 +87,124 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij
|
||||
}
|
||||
```
|
||||
|
||||
Chrome 会以已登录的 Chrome 配置文件身份加入。在 Meet 中,选择 `BlackHole 2ch` 作为 OpenClaw 使用的麦克风/扬声器路径。为了获得干净的全双工音频,请使用单独的虚拟设备或类似 Loopback 的图形;单个 BlackHole 设备足以完成首次 smoke test,但可能会产生回声。
|
||||
Chrome 会以已登录的 Chrome 配置文件身份加入。在 Meet 中,选择 `BlackHole 2ch` 作为 OpenClaw 使用的麦克风/扬声器路径。为了获得干净的双工音频,请使用独立的虚拟设备或类似 Loopback 的音频路由图;单个 BlackHole 设备足以完成第一次冒烟测试,但可能会产生回声。
|
||||
|
||||
### 本地 Gateway 网关 + Parallels Chrome
|
||||
|
||||
你**不**需要在 macOS VM 中运行完整的 OpenClaw Gateway 网关 或配置模型 API 密钥,才能让 VM 承担 Chrome 的运行。你可以在本地运行 Gateway 网关和智能体,然后在 VM 中运行一个节点主机。只需在 VM 中启用一次内置插件,这样节点就会通告 Chrome 命令:
|
||||
|
||||
各组件运行位置如下:
|
||||
|
||||
- Gateway 网关主机:OpenClaw Gateway 网关、智能体工作区、模型/API 密钥、实时提供商,以及 Google Meet 插件配置。
|
||||
- Parallels macOS VM:OpenClaw CLI/节点主机、Google Chrome、SoX、BlackHole 2ch,以及一个已登录 Google 的 Chrome 配置文件。
|
||||
- VM 中不需要:Gateway 网关服务、智能体配置、OpenAI/GPT 密钥或模型提供商设置。
|
||||
|
||||
安装 VM 依赖:
|
||||
|
||||
```bash
|
||||
brew install blackhole-2ch sox
|
||||
```
|
||||
|
||||
安装 BlackHole 后重启 VM,这样 macOS 才会显示 `BlackHole 2ch`:
|
||||
|
||||
```bash
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
重启后,验证 VM 可以看到音频设备和 SoX 命令:
|
||||
|
||||
```bash
|
||||
system_profiler SPAudioDataType | grep -i BlackHole
|
||||
command -v rec play
|
||||
```
|
||||
|
||||
在 VM 中安装或更新 OpenClaw,然后在那里启用内置插件:
|
||||
|
||||
```bash
|
||||
openclaw plugins enable google-meet
|
||||
```
|
||||
|
||||
在 VM 中启动节点主机:
|
||||
|
||||
```bash
|
||||
openclaw node run --host <gateway-host> --port 18789 --display-name parallels-macos
|
||||
```
|
||||
|
||||
在 Gateway 网关主机上批准该节点:
|
||||
|
||||
```bash
|
||||
openclaw devices list
|
||||
openclaw devices approve <requestId>
|
||||
```
|
||||
|
||||
确认 Gateway 网关能看到该节点,并且它通告了 `googlemeet.chrome`:
|
||||
|
||||
```bash
|
||||
openclaw nodes status
|
||||
```
|
||||
|
||||
在 Gateway 网关主机上通过该节点路由 Meet:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
"google-meet": {
|
||||
enabled: true,
|
||||
config: {
|
||||
defaultTransport: "chrome-node",
|
||||
chromeNode: {
|
||||
node: "parallels-macos",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
现在可以像平常一样从 Gateway 网关主机加入:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
或者请求智能体使用 `google_meet` 工具并设置 `transport: "chrome-node"`。
|
||||
|
||||
如果省略 `chromeNode.node`,只有在恰好有一个已连接节点通告 `googlemeet.chrome` 时,OpenClaw 才会自动选择。如果连接了多个有能力的节点,请将 `chromeNode.node` 设置为节点 id、显示名称或远程 IP。
|
||||
|
||||
常见故障检查:
|
||||
|
||||
- `No connected Google Meet-capable node`:在 VM 中启动 `openclaw node run`,批准配对,并确保已经在 VM 中运行过 `openclaw plugins enable google-meet`。
|
||||
- `BlackHole 2ch audio device not found on the node`:在 VM 中安装 `blackhole-2ch`,然后重启 VM。
|
||||
- Chrome 打开但无法加入:在 VM 内登录 Chrome,并确认该配置文件可以手动加入该 Meet URL。
|
||||
- 没有音频:在 Meet 中,将麦克风/扬声器路由到 OpenClaw 使用的虚拟音频设备路径;为了获得干净的双工音频,请使用独立的虚拟设备或类似 Loopback 的路由方式。
|
||||
|
||||
## 安装说明
|
||||
|
||||
Chrome realtime 默认路径使用两个外部工具:
|
||||
Chrome 实时默认路径使用两个外部工具:
|
||||
|
||||
- `sox`:命令行音频工具。插件使用其 `rec` 和 `play` 命令作为默认的 8 kHz G.711 mu-law 音频桥接。
|
||||
- `blackhole-2ch`:macOS 虚拟音频驱动。它会创建 `BlackHole 2ch` 音频设备,供 Chrome / Meet 路由使用。
|
||||
- `sox`:命令行音频工具。该插件使用它的 `rec` 和 `play` 命令来实现默认的 8 kHz G.711 mu-law 音频桥接。
|
||||
- `blackhole-2ch`:macOS 虚拟音频驱动。它会创建 `BlackHole 2ch` 音频设备,供 Chrome/Meet 进行音频路由。
|
||||
|
||||
OpenClaw 不会捆绑或重新分发这两个软件包。文档要求用户通过 Homebrew 将其作为主机依赖安装。SoX 的许可证为 `LGPL-2.0-only AND GPL-2.0-only`;BlackHole 为 GPL-3.0。如果你要构建一个将 BlackHole 与 OpenClaw 一起捆绑的安装程序或设备,请审查 BlackHole 上游许可条款,或向 Existential Audio 获取单独许可。
|
||||
OpenClaw 不捆绑也不重新分发这两个软件包。文档要求用户通过 Homebrew 将它们作为主机依赖安装。SoX 的许可证是 `LGPL-2.0-only AND GPL-2.0-only`;BlackHole 是 GPL-3.0。如果你构建了一个将 BlackHole 与 OpenClaw 一起捆绑的安装程序或设备,请审查 BlackHole 上游许可条款,或从 Existential Audio 获取单独许可证。
|
||||
|
||||
## 传输方式
|
||||
|
||||
### Chrome
|
||||
|
||||
Chrome 传输方式会在 Google Chrome 中打开 Meet URL,并以已登录的 Chrome 配置文件身份加入。在 macOS 上,插件会在启动前检查 `BlackHole 2ch`。如果有配置,它还会在打开 Chrome 之前运行音频桥接健康检查命令和启动命令。
|
||||
Chrome 传输方式会在 Google Chrome 中打开 Meet URL,并以已登录的 Chrome 配置文件身份加入。在 macOS 上,插件会在启动前检查 `BlackHole 2ch`。如果已配置,它还会在打开 Chrome 之前运行音频桥健康检查命令和启动命令。当 Chrome/音频位于 Gateway 网关主机上时使用 `chrome`;当 Chrome/音频位于已配对节点(例如 Parallels macOS VM)上时使用 `chrome-node`。
|
||||
|
||||
```bash
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome-node
|
||||
```
|
||||
|
||||
通过本地 OpenClaw 音频桥接来路由 Chrome 麦克风和扬声器音频。如果未安装 `BlackHole 2ch`,加入会因设置错误而失败,而不是在没有音频路径的情况下静默加入。
|
||||
将 Chrome 的麦克风和扬声器音频通过本地 OpenClaw 音频桥进行路由。如果未安装 `BlackHole 2ch`,加入操作会以设置错误失败,而不是在没有音频路径的情况下静默加入。
|
||||
|
||||
### Twilio
|
||||
|
||||
Twilio 传输方式是一个严格的拨号计划,并委托给 Voice Call 插件。它不会解析 Meet 页面中的电话号码。
|
||||
Twilio 传输方式是一个严格的拨号计划,并委托给 Voice Call 插件处理。它不会从 Meet 页面解析电话号码。
|
||||
|
||||
```bash
|
||||
openclaw googlemeet join https://meet.google.com/abc-defg-hij \
|
||||
@ -131,16 +224,15 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \
|
||||
|
||||
## OAuth 和预检
|
||||
|
||||
Google Meet Media API 访问优先使用个人 OAuth 客户端。配置
|
||||
`oauth.clientId`,并可选配置 `oauth.clientSecret`,然后运行:
|
||||
Google Meet Media API 访问首先使用个人 OAuth 客户端。配置 `oauth.clientId`,并可选配置 `oauth.clientSecret`,然后运行:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet auth login --json
|
||||
```
|
||||
|
||||
该命令会输出一个带有 refresh token 的 `oauth` 配置块。它使用 PKCE、位于 `http://localhost:8085/oauth2callback` 的 localhost 回调,以及通过 `--manual` 实现的手动复制/粘贴流程。
|
||||
该命令会打印一个带有刷新令牌的 `oauth` 配置块。它使用 PKCE、位于 `http://localhost:8085/oauth2callback` 的 localhost 回调,以及通过 `--manual` 进行的手动复制/粘贴流程。
|
||||
|
||||
以下环境变量可作为回退:
|
||||
以下环境变量可作为回退值使用:
|
||||
|
||||
- `OPENCLAW_GOOGLE_MEET_CLIENT_ID` 或 `GOOGLE_MEET_CLIENT_ID`
|
||||
- `OPENCLAW_GOOGLE_MEET_CLIENT_SECRET` 或 `GOOGLE_MEET_CLIENT_SECRET`
|
||||
@ -151,23 +243,23 @@ openclaw googlemeet auth login --json
|
||||
- `OPENCLAW_GOOGLE_MEET_DEFAULT_MEETING` 或 `GOOGLE_MEET_DEFAULT_MEETING`
|
||||
- `OPENCLAW_GOOGLE_MEET_PREVIEW_ACK` 或 `GOOGLE_MEET_PREVIEW_ACK`
|
||||
|
||||
通过 `spaces.get` 解析 Meet URL、代码或 `spaces/{id}`:
|
||||
通过 `spaces.get` 解析 Meet URL、会议代码或 `spaces/{id}`:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
在处理媒体前运行预检:
|
||||
在进行媒体工作之前运行预检:
|
||||
|
||||
```bash
|
||||
openclaw googlemeet preflight --meeting https://meet.google.com/abc-defg-hij
|
||||
```
|
||||
|
||||
只有在确认你的 Cloud 项目、OAuth 主体和会议参与者都已加入 Google Workspace Developer Preview Program for Meet media APIs 后,才设置 `preview.enrollmentAcknowledged: true`。
|
||||
仅在确认你的 Cloud 项目、OAuth 主体和会议参与者都已加入 Google Workspace Developer Preview Program for Meet media APIs 后,才设置 `preview.enrollmentAcknowledged: true`。
|
||||
|
||||
## 配置
|
||||
|
||||
常见的 Chrome realtime 路径只需要启用插件、BlackHole、SoX 和一个 OpenAI 密钥:
|
||||
常见的 Chrome 实时路径只需要启用该插件、安装 BlackHole、SoX,以及一个 OpenAI 密钥:
|
||||
|
||||
```bash
|
||||
brew install blackhole-2ch sox
|
||||
@ -193,15 +285,14 @@ export OPENAI_API_KEY=sk-...
|
||||
|
||||
- `defaultTransport: "chrome"`
|
||||
- `defaultMode: "realtime"`
|
||||
- `chromeNode.node`:`chrome-node` 的可选节点 id/名称/IP
|
||||
- `chrome.audioBackend: "blackhole-2ch"`
|
||||
- `chrome.audioInputCommand`:将 8 kHz G.711 mu-law
|
||||
音频写入 stdout 的 SoX `rec` 命令
|
||||
- `chrome.audioOutputCommand`:从 stdin 读取 8 kHz G.711 mu-law
|
||||
音频的 SoX `play` 命令
|
||||
- `chrome.audioInputCommand`:将 8 kHz G.711 mu-law 音频写入 stdout 的 SoX `rec` 命令
|
||||
- `chrome.audioOutputCommand`:从 stdin 读取 8 kHz G.711 mu-law 音频的 SoX `play` 命令
|
||||
- `realtime.provider: "openai"`
|
||||
- `realtime.toolPolicy: "safe-read-only"`
|
||||
- `realtime.instructions`:简短口头回复,必要时使用
|
||||
`openclaw_agent_consult` 获取更深入的回答
|
||||
- `realtime.instructions`:简短的口头回复,深入回答时使用
|
||||
`openclaw_agent_consult`
|
||||
|
||||
可选覆盖项:
|
||||
|
||||
@ -213,13 +304,16 @@ export OPENAI_API_KEY=sk-...
|
||||
chrome: {
|
||||
browserProfile: "Default",
|
||||
},
|
||||
chromeNode: {
|
||||
node: "parallels-macos",
|
||||
},
|
||||
realtime: {
|
||||
toolPolicy: "owner",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
仅 Twilio 配置:
|
||||
仅适用于 Twilio 的配置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -242,46 +336,46 @@ export OPENAI_API_KEY=sk-...
|
||||
{
|
||||
"action": "join",
|
||||
"url": "https://meet.google.com/abc-defg-hij",
|
||||
"transport": "chrome",
|
||||
"transport": "chrome-node",
|
||||
"mode": "realtime"
|
||||
}
|
||||
```
|
||||
|
||||
使用 `action: "status"` 可列出活动会话或检查某个会话 ID。使用
|
||||
`action: "leave"` 可将某个会话标记为已结束。
|
||||
当 Chrome 在 Gateway 网关主机上运行时,使用 `transport: "chrome"`。当 Chrome 在已配对节点(例如 Parallels VM)上运行时,使用 `transport: "chrome-node"`。这两种情况下,实时模型和 `openclaw_agent_consult` 都运行在 Gateway 网关主机上,因此模型凭证会保留在那里。
|
||||
|
||||
使用 `action: "status"` 可列出活动会话或检查某个会话 ID。使用 `action: "leave"` 可将会话标记为已结束。
|
||||
|
||||
## 实时智能体咨询
|
||||
|
||||
Chrome realtime 模式针对实时语音循环进行了优化。实时语音提供商会听取会议音频,并通过已配置的音频桥接进行发声。当实时模型需要更深入的推理、当前信息或常规 OpenClaw 工具时,它可以调用 `openclaw_agent_consult`。
|
||||
Chrome 实时模式针对实时语音循环进行了优化。实时语音提供商会听取会议音频,并通过已配置的音频桥发声。当实时模型需要更深入的推理、最新信息或常规 OpenClaw 工具时,它可以调用 `openclaw_agent_consult`。
|
||||
|
||||
咨询工具会在幕后运行常规 OpenClaw 智能体,附带最近的会议转录上下文,并向实时语音会话返回一个简洁的口头回答。然后语音模型就可以将该回答说回会议中。
|
||||
咨询工具会在后台运行常规 OpenClaw 智能体,携带最近的会议转录上下文,并向实时语音会话返回简洁的口头回答。然后,语音模型可以将该回答再次说回会议中。
|
||||
|
||||
`realtime.toolPolicy` 控制咨询运行:
|
||||
`realtime.toolPolicy` 控制咨询运行方式:
|
||||
|
||||
- `safe-read-only`:暴露咨询工具,并将常规智能体限制为
|
||||
- `safe-read-only`:公开咨询工具,并将常规智能体限制为使用
|
||||
`read`、`web_search`、`web_fetch`、`x_search`、`memory_search` 和
|
||||
`memory_get`。
|
||||
- `owner`:暴露咨询工具,并允许常规智能体使用正常的智能体工具策略。
|
||||
- `none`:不向实时语音模型暴露咨询工具。
|
||||
- `owner`:公开咨询工具,并允许常规智能体使用普通的智能体工具策略。
|
||||
- `none`:不向实时语音模型公开咨询工具。
|
||||
|
||||
咨询会话键按每个 Meet 会话进行作用域划分,因此在同一场会议中,后续咨询调用可以复用先前的咨询上下文。
|
||||
咨询会话键按 Meet 会话进行作用域隔离,因此在同一场会议期间,后续咨询调用可以复用先前的咨询上下文。
|
||||
|
||||
## 说明
|
||||
|
||||
Google Meet 的官方媒体 API 以接收为导向,因此向 Meet 通话中发声仍然需要一个参与者路径。这个插件会保持该边界清晰可见:Chrome 负责浏览器参与和本地音频路由;Twilio 负责电话拨入参与。
|
||||
Google Meet 官方媒体 API 偏向接收,因此要在 Meet 通话中发言,仍然需要一个参与者路径。该插件会将这一边界保持为可见状态:Chrome 处理浏览器参与和本地音频路由;Twilio 处理电话拨入参与。
|
||||
|
||||
Chrome realtime 模式需要以下两者之一:
|
||||
Chrome 实时模式需要以下两种方式之一:
|
||||
|
||||
- `chrome.audioInputCommand` 加 `chrome.audioOutputCommand`:OpenClaw 接管
|
||||
realtime 模型桥接,并在这些命令与所选 realtime 语音提供商之间传输 8 kHz G.711 mu-law 音频。
|
||||
- `chrome.audioBridgeCommand`:由外部桥接命令接管整个本地音频路径,并且在启动或验证其守护进程后必须退出。
|
||||
- `chrome.audioInputCommand` 加 `chrome.audioOutputCommand`:OpenClaw 拥有实时模型桥,并在这些命令与所选实时语音提供商之间传输 8 kHz G.711 mu-law 音频。
|
||||
- `chrome.audioBridgeCommand`:外部桥接命令拥有整个本地音频路径,并且必须在启动或验证其守护进程后退出。
|
||||
|
||||
为了获得干净的全双工音频,请通过单独的虚拟设备或类似 Loopback 的虚拟设备图形来路由 Meet 输出和 Meet 麦克风。单个共享的 BlackHole 设备可能会将其他参与者的声音回送到通话中。
|
||||
为了获得干净的双工音频,请将 Meet 输出和 Meet 麦克风分别路由到独立的虚拟设备,或使用类似 Loopback 的虚拟设备图。单个共享的 BlackHole 设备可能会把其他参与者的声音回送到通话中。
|
||||
|
||||
对于 Chrome 会话,`googlemeet leave` 会停止命令对形式的 realtime 音频桥接。对于通过 Voice Call 插件委托的 Twilio 会话,它还会挂断底层语音通话。
|
||||
`googlemeet leave` 会停止用于 Chrome 会话的命令对实时音频桥。对于通过 Voice Call 插件委托的 Twilio 会话,它还会挂断底层语音通话。
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [Voice call 插件](/zh-CN/plugins/voice-call)
|
||||
- [Talk 模式](/zh-CN/nodes/talk)
|
||||
- [通话模式](/zh-CN/nodes/talk)
|
||||
- [构建插件](/zh-CN/plugins/building-plugins)
|
||||
|
||||
@ -1,24 +1,26 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要从插件中调用核心辅助工具(TTS、STT、图像生成、Web 搜索、子智能体)
|
||||
- 你需要从插件调用核心辅助方法(TTS、STT、图像生成、网络搜索、子智能体、节点)
|
||||
- 你想了解 `api.runtime` 暴露了什么
|
||||
- 你正在从插件代码中访问配置、智能体或媒体辅助工具
|
||||
- 你正在从插件代码中访问配置、智能体或媒体辅助方法
|
||||
sidebarTitle: Runtime Helpers
|
||||
summary: api.runtime —— 可供插件使用的注入式运行时辅助工具
|
||||
title: 插件运行时辅助工具
|
||||
summary: '`api.runtime`——提供给插件的注入式运行时辅助方法'
|
||||
title: 插件运行时辅助方法
|
||||
x-i18n:
|
||||
generated_at: "2026-04-23T22:45:07Z"
|
||||
generated_at: "2026-04-24T04:34:53Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 63069008df16baebbe1ad0189af9002761d3829c4a71bdbf9d753fc51d40741f
|
||||
source_hash: 2327bdabc0dc1e05000ff83e507007fadff2698cceaae0d4a3e7bc4885440c55
|
||||
source_path: plugins/sdk-runtime.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
在注册期间注入到每个插件中的 `api.runtime` 对象参考。请使用这些辅助工具,而不要直接导入宿主内部实现。
|
||||
注册期间注入到每个插件中的 `api.runtime` 对象参考。请使用这些辅助方法,而不要直接导入宿主内部实现。
|
||||
|
||||
<Tip>
|
||||
**想看操作演练?** 请参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins) 或 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) 中的分步指南,这些指南会结合上下文展示这些辅助工具的用法。
|
||||
**想看操作演练?** 请参阅 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)
|
||||
或 [提供商插件](/zh-CN/plugins/sdk-provider-plugins) 的分步指南,
|
||||
这些指南会结合上下文展示这些辅助方法的用法。
|
||||
</Tip>
|
||||
|
||||
```typescript
|
||||
@ -34,7 +36,7 @@ register(api) {
|
||||
智能体身份、目录和会话管理。
|
||||
|
||||
```typescript
|
||||
// 解析智能体工作目录
|
||||
// 解析智能体的工作目录
|
||||
const agentDir = api.runtime.agent.resolveAgentDir(cfg);
|
||||
|
||||
// 解析智能体工作区
|
||||
@ -52,7 +54,7 @@ const timeoutMs = api.runtime.agent.resolveAgentTimeoutMs(cfg);
|
||||
// 确保工作区存在
|
||||
await api.runtime.agent.ensureAgentWorkspace(cfg);
|
||||
|
||||
// 运行一次嵌入式智能体回合
|
||||
// 运行一个嵌入式智能体轮次
|
||||
const agentDir = api.runtime.agent.resolveAgentDir(cfg);
|
||||
const result = await api.runtime.agent.runEmbeddedAgent({
|
||||
sessionId: "my-plugin:task-1",
|
||||
@ -64,11 +66,12 @@ const result = await api.runtime.agent.runEmbeddedAgent({
|
||||
});
|
||||
```
|
||||
|
||||
`runEmbeddedAgent(...)` 是用于从插件代码中启动标准 OpenClaw 智能体回合的中立辅助工具。它使用与渠道触发回复相同的 provider/模型解析和智能体 harness 选择逻辑。
|
||||
`runEmbeddedAgent(...)` 是一个中立的辅助方法,用于从插件代码启动一次普通的 OpenClaw
|
||||
智能体轮次。它使用与渠道触发回复相同的提供商/模型解析逻辑,以及相同的智能体 harness 选择逻辑。
|
||||
|
||||
`runEmbeddedPiAgent(...)` 仍然保留为兼容性别名。
|
||||
`runEmbeddedPiAgent(...)` 仍然保留,作为兼容性别名。
|
||||
|
||||
**会话存储辅助工具** 位于 `api.runtime.agent.session` 下:
|
||||
**会话存储辅助方法** 位于 `api.runtime.agent.session` 下:
|
||||
|
||||
```typescript
|
||||
const storePath = api.runtime.agent.session.resolveStorePath(cfg);
|
||||
@ -88,10 +91,10 @@ const provider = api.runtime.agent.defaults.provider; // 例如 "anthropic"
|
||||
|
||||
### `api.runtime.subagent`
|
||||
|
||||
启动和管理后台子智能体运行。
|
||||
启动并管理后台子智能体运行。
|
||||
|
||||
```typescript
|
||||
// 启动一次子智能体运行
|
||||
// 启动一个子智能体运行
|
||||
const { runId } = await api.runtime.subagent.run({
|
||||
sessionKey: "agent:main:subagent:search-helper",
|
||||
message: "Expand this query into focused follow-up searches.",
|
||||
@ -109,20 +112,39 @@ const { messages } = await api.runtime.subagent.getSessionMessages({
|
||||
limit: 10,
|
||||
});
|
||||
|
||||
// 删除会话
|
||||
// 删除一个会话
|
||||
await api.runtime.subagent.deleteSession({
|
||||
sessionKey: "agent:main:subagent:search-helper",
|
||||
});
|
||||
```
|
||||
|
||||
<Warning>
|
||||
模型覆盖(`provider`/`model`)需要操作员在配置中显式启用 `plugins.entries.<id>.subagent.allowModelOverride: true`。
|
||||
模型覆盖(`provider`/`model`)要求操作员在配置中显式启用
|
||||
`plugins.entries.<id>.subagent.allowModelOverride: true`。
|
||||
不受信任的插件仍然可以运行子智能体,但覆盖请求会被拒绝。
|
||||
</Warning>
|
||||
|
||||
### `api.runtime.nodes`
|
||||
|
||||
列出已连接的节点,并从 Gateway 网关加载的插件代码中调用节点宿主命令。
|
||||
当插件在配对设备上拥有本地工作时,请使用此方法,例如在另一台 Mac 上运行的浏览器桥接或音频桥接。
|
||||
|
||||
```typescript
|
||||
const { nodes } = await api.runtime.nodes.list({ connected: true });
|
||||
|
||||
const result = await api.runtime.nodes.invoke({
|
||||
nodeId: "mac-studio",
|
||||
command: "my-plugin.command",
|
||||
params: { action: "start" },
|
||||
timeoutMs: 30000,
|
||||
});
|
||||
```
|
||||
|
||||
此运行时仅在 Gateway 网关内部可用。节点命令仍然会经过正常的 Gateway 网关节点配对、命令允许列表和节点本地命令处理流程。
|
||||
|
||||
### `api.runtime.taskFlow`
|
||||
|
||||
将 Task Flow 运行时绑定到现有的 OpenClaw 会话键或受信任的工具上下文,然后在无需每次调用都传入所有者的情况下创建和管理 Task Flow。
|
||||
将 Task Flow 运行时绑定到现有的 OpenClaw 会话键或受信任的工具上下文,然后在每次调用时无需传递 owner,即可创建和管理 Task Flow。
|
||||
|
||||
```typescript
|
||||
const taskFlow = api.runtime.taskFlow.fromToolContext(ctx);
|
||||
@ -149,7 +171,8 @@ const waiting = taskFlow.setWaiting({
|
||||
});
|
||||
```
|
||||
|
||||
当你已经从自己的绑定层获得一个受信任的 OpenClaw 会话键时,请使用 `bindSession({ sessionKey, requesterOrigin })`。不要从原始用户输入进行绑定。
|
||||
如果你已经从自己的绑定层获得了一个受信任的 OpenClaw 会话键,请使用
|
||||
`bindSession({ sessionKey, requesterOrigin })`。不要从原始用户输入进行绑定。
|
||||
|
||||
### `api.runtime.tts`
|
||||
|
||||
@ -175,14 +198,14 @@ const voices = await api.runtime.tts.listVoices({
|
||||
});
|
||||
```
|
||||
|
||||
使用核心 `messages.tts` 配置和提供商选择。返回 PCM 音频缓冲区和采样率。
|
||||
使用核心 `messages.tts` 配置和提供商选择逻辑。返回 PCM 音频缓冲区和采样率。
|
||||
|
||||
### `api.runtime.mediaUnderstanding`
|
||||
|
||||
图像、音频和视频分析。
|
||||
|
||||
```typescript
|
||||
// 描述图像
|
||||
// 描述一张图像
|
||||
const image = await api.runtime.mediaUnderstanding.describeImageFile({
|
||||
filePath: "/tmp/inbound-photo.jpg",
|
||||
cfg: api.config,
|
||||
@ -196,7 +219,7 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
|
||||
mime: "audio/ogg", // 可选,用于无法推断 MIME 的情况
|
||||
});
|
||||
|
||||
// 描述视频
|
||||
// 描述一段视频
|
||||
const video = await api.runtime.mediaUnderstanding.describeVideoFile({
|
||||
filePath: "/tmp/inbound-video.mp4",
|
||||
cfg: api.config,
|
||||
@ -209,10 +232,11 @@ const result = await api.runtime.mediaUnderstanding.runFile({
|
||||
});
|
||||
```
|
||||
|
||||
当未产生输出时(例如输入被跳过),返回 `{ text: undefined }`。
|
||||
当未产生输出时(例如跳过输入),返回 `{ text: undefined }`。
|
||||
|
||||
<Info>
|
||||
`api.runtime.stt.transcribeAudioFile(...)` 仍然保留为 `api.runtime.mediaUnderstanding.transcribeAudioFile(...)` 的兼容性别名。
|
||||
`api.runtime.stt.transcribeAudioFile(...)` 仍然保留,作为
|
||||
`api.runtime.mediaUnderstanding.transcribeAudioFile(...)` 的兼容性别名。
|
||||
</Info>
|
||||
|
||||
### `api.runtime.imageGeneration`
|
||||
@ -230,7 +254,7 @@ const providers = api.runtime.imageGeneration.listProviders({ cfg: api.config })
|
||||
|
||||
### `api.runtime.webSearch`
|
||||
|
||||
Web 搜索。
|
||||
网络搜索。
|
||||
|
||||
```typescript
|
||||
const providers = api.runtime.webSearch.listProviders({ config: api.config });
|
||||
@ -243,7 +267,7 @@ const result = await api.runtime.webSearch.search({
|
||||
|
||||
### `api.runtime.media`
|
||||
|
||||
底层媒体实用工具。
|
||||
底层媒体工具。
|
||||
|
||||
```typescript
|
||||
const webMedia = await api.runtime.media.loadWebMedia(url);
|
||||
@ -277,7 +301,7 @@ await api.runtime.config.writeConfigFile(cfg);
|
||||
|
||||
### `api.runtime.system`
|
||||
|
||||
系统级实用工具。
|
||||
系统级工具。
|
||||
|
||||
```typescript
|
||||
await api.runtime.system.enqueueSystemEvent(event);
|
||||
@ -310,7 +334,7 @@ const childLogger = api.runtime.logging.getChildLogger({ plugin: "my-plugin" },
|
||||
|
||||
### `api.runtime.modelAuth`
|
||||
|
||||
模型和提供商凭证解析。
|
||||
模型和提供商认证解析。
|
||||
|
||||
```typescript
|
||||
const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg });
|
||||
@ -340,7 +364,7 @@ api.runtime.tools.registerMemoryCli(/* ... */);
|
||||
|
||||
### `api.runtime.channel`
|
||||
|
||||
渠道特定的运行时辅助工具(在加载渠道插件时可用)。
|
||||
渠道专用运行时辅助方法(在加载渠道插件时可用)。
|
||||
|
||||
`api.runtime.channel.mentions` 是供使用运行时注入的内置渠道插件共享的入站提及策略接口:
|
||||
|
||||
@ -369,7 +393,7 @@ const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({
|
||||
});
|
||||
```
|
||||
|
||||
可用的提及辅助工具:
|
||||
可用的提及辅助方法:
|
||||
|
||||
- `buildMentionRegexes`
|
||||
- `matchesMentionPatterns`
|
||||
@ -377,11 +401,14 @@ const decision = api.runtime.channel.mentions.resolveInboundMentionDecision({
|
||||
- `implicitMentionKindWhen`
|
||||
- `resolveInboundMentionDecision`
|
||||
|
||||
`api.runtime.channel.mentions` 有意不暴露旧版的 `resolveMentionGating*` 兼容性辅助工具。请优先使用标准化的 `{ facts, policy }` 路径。
|
||||
`api.runtime.channel.mentions` 有意不暴露旧版的
|
||||
`resolveMentionGating*` 兼容性辅助方法。请优先使用标准化的
|
||||
`{ facts, policy }` 路径。
|
||||
|
||||
## 存储运行时引用
|
||||
|
||||
使用 `createPluginRuntimeStore` 存储运行时引用,以便在 `register` 回调之外使用:
|
||||
使用 `createPluginRuntimeStore` 存储运行时引用,以便在 `register`
|
||||
回调之外使用:
|
||||
|
||||
```typescript
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
||||
@ -403,7 +430,7 @@ export default defineChannelPluginEntry({
|
||||
|
||||
// 在其他文件中
|
||||
export function getRuntime() {
|
||||
return store.getRuntime(); // 如果未初始化则抛出异常
|
||||
return store.getRuntime(); // 如果未初始化则抛出
|
||||
}
|
||||
|
||||
export function tryGetRuntime() {
|
||||
@ -411,7 +438,7 @@ export function tryGetRuntime() {
|
||||
}
|
||||
```
|
||||
|
||||
对于运行时存储的标识,优先使用 `pluginId`。更底层的 `key` 形式适用于少见场景,即某个插件有意需要多个运行时槽位。
|
||||
对于 runtime-store 标识,优先使用 `pluginId`。更底层的 `key` 形式适用于少见场景,即一个插件有意需要多个运行时槽位的情况。
|
||||
|
||||
## 其他顶层 `api` 字段
|
||||
|
||||
@ -421,14 +448,14 @@ export function tryGetRuntime() {
|
||||
| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| `api.id` | `string` | 插件 id |
|
||||
| `api.name` | `string` | 插件显示名称 |
|
||||
| `api.config` | `OpenClawConfig` | 当前配置快照(在可用时为活动的内存中运行时快照) |
|
||||
| `api.config` | `OpenClawConfig` | 当前配置快照(如果可用,则为活动的内存中运行时快照) |
|
||||
| `api.pluginConfig` | `Record<string, unknown>` | 来自 `plugins.entries.<id>.config` 的插件专属配置 |
|
||||
| `api.logger` | `PluginLogger` | 作用域日志记录器(`debug`、`info`、`warn`、`error`) |
|
||||
| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口启动/设置前的轻量级启动/设置窗口 |
|
||||
| `api.registrationMode` | `PluginRegistrationMode` | 当前加载模式;`"setup-runtime"` 是完整入口启动/设置之前的轻量预启动/设置窗口 |
|
||||
| `api.resolvePath(input)` | `(string) => string` | 解析相对于插件根目录的路径 |
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [SDK 概览](/zh-CN/plugins/sdk-overview) -- 子路径参考
|
||||
- [SDK 入口点](/zh-CN/plugins/sdk-entrypoints) -- `definePluginEntry` 选项
|
||||
- [SDK Entry Points](/zh-CN/plugins/sdk-entrypoints) -- `definePluginEntry` 选项
|
||||
- [插件内部机制](/zh-CN/plugins/architecture) -- 能力模型和注册表
|
||||
|
||||
Loading…
Reference in New Issue
Block a user