diff --git a/docs/zh-CN/providers/google.md b/docs/zh-CN/providers/google.md index ef1ac6452..2f9a96ee5 100644 --- a/docs/zh-CN/providers/google.md +++ b/docs/zh-CN/providers/google.md @@ -1,34 +1,32 @@ --- read_when: - 你想在 OpenClaw 中使用 Google Gemini 模型 - - 你需要 API 密钥或 OAuth 身份验证流程 -summary: Google Gemini 设置(API 密钥 + OAuth、图片生成、媒体理解、TTS、Web 搜索) + - 你需要 API 密钥或 OAuth 认证流程 +summary: Google Gemini 设置(API 密钥 + OAuth、图像生成、媒体理解、TTS、网页搜索) title: Google(Gemini) x-i18n: - generated_at: "2026-04-23T21:00:27Z" + generated_at: "2026-04-24T08:40:02Z" model: gpt-5.4 provider: openai - source_hash: b43d7171f56ecdfb49a25256783433e64f99a02760b3bc6f0e1055195f556f5d + source_hash: 7e66c9dd637e26976659d04b9b7e2452e6881945dab6011970f9e1c5e4a9a685 source_path: providers/google.md workflow: 15 --- -Google 插件通过 Google AI Studio 提供 Gemini 模型访问,还支持 -图片生成、媒体理解(图片/音频/视频)、文本转语音,以及通过 -Gemini Grounding 实现 Web 搜索。 +Google 插件通过 Google AI Studio 提供对 Gemini 模型的访问,此外还支持通过 Gemini Grounding 实现图像生成、媒体理解(图像/音频/视频)、文本转语音以及网页搜索。 - 提供商:`google` -- 身份验证:`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` +- 认证:`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` - API:Google Gemini API -- 替代提供商:`google-gemini-cli`(OAuth) +- 备选提供商:`google-gemini-cli`(OAuth) ## 入门指南 -选择你偏好的身份验证方式,并按照设置步骤操作。 +选择你偏好的认证方式,并按照设置步骤操作。 - **最适合:** 通过 Google AI Studio 进行标准 Gemini API 访问。 + **最适合:** 通过 Google AI Studio 进行标准的 Gemini API 访问。 @@ -56,7 +54,7 @@ Gemini Grounding 实现 Web 搜索。 } ``` - + ```bash openclaw models list --provider google ``` @@ -64,40 +62,38 @@ Gemini Grounding 实现 Web 搜索。 - `GEMINI_API_KEY` 和 `GOOGLE_API_KEY` 这两个环境变量都可接受。使用你已经配置好的那个即可。 + 环境变量 `GEMINI_API_KEY` 和 `GOOGLE_API_KEY` 都可以使用。使用你已经配置好的那个即可。 - **最适合:** 复用已有的 Gemini CLI 登录,通过 PKCE OAuth,而不是单独使用 API 密钥。 + **最适合:** 通过 PKCE OAuth 复用现有的 Gemini CLI 登录,而不是单独使用一个 API 密钥。 - `google-gemini-cli` 提供商属于非官方集成。有些用户 - 报告过以这种方式使用 OAuth 时会遇到账户限制。请自行承担风险。 + `google-gemini-cli` 提供商是一个非官方集成。一些用户报告称,以这种方式使用 OAuth 时会遇到账户限制。请自行承担风险。 - 本地 `gemini` 命令必须在 `PATH` 中可用。 + 本地 `gemini` 命令必须可在 `PATH` 中使用。 ```bash # Homebrew brew install gemini-cli - # 或 npm + # or npm npm install -g @google/gemini-cli ``` - OpenClaw 同时支持 Homebrew 安装和全局 npm 安装,包括 - 常见的 Windows/npm 布局。 + OpenClaw 同时支持 Homebrew 安装和全局 npm 安装,包括常见的 Windows/npm 布局。 ```bash openclaw models auth login --provider google-gemini-cli --set-default ``` - + ```bash openclaw models list --provider google-gemini-cli ``` @@ -112,63 +108,52 @@ Gemini Grounding 实现 Web 搜索。 - `OPENCLAW_GEMINI_OAUTH_CLIENT_ID` - `OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET` - (或者使用 `GEMINI_CLI_*` 变体。) + (或 `GEMINI_CLI_*` 变体。) - 如果 Gemini CLI OAuth 在登录后请求失败,请在 gateway 主机上设置 `GOOGLE_CLOUD_PROJECT` 或 - `GOOGLE_CLOUD_PROJECT_ID`,然后重试。 + 如果 Gemini CLI OAuth 请求在登录后失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`,然后重试。 - 如果在浏览器流程启动前登录就失败,请确认本地 `gemini` - 命令已安装并位于 `PATH` 中。 + 如果在浏览器流程开始之前登录就失败,请确认本地 `gemini` 命令已安装并且位于 `PATH` 中。 - 仅 OAuth 的 `google-gemini-cli` 提供商是一个独立的文本推理 - 接口。图片生成、媒体理解和 Gemini Grounding 仍归属于 - `google` 提供商 id。 - + 仅支持 OAuth 的 `google-gemini-cli` 提供商是一个独立的文本推理入口。图像生成、媒体理解和 Gemini Grounding 仍然归属于 `google` 提供商 id。 ## 功能 -| 功能 | 是否支持 | +| 功能 | 支持情况 | | ---------------------- | ----------------------------- | -| 聊天补全 | 是 | -| 图片生成 | 是 | -| 音乐生成 | 是 | -| 文本转语音 | 是 | -| 图片理解 | 是 | -| 音频转录 | 是 | -| 视频理解 | 是 | -| Web 搜索(Grounding) | 是 | -| Thinking/推理 | 是(Gemini 2.5+ / Gemini 3+) | -| Gemma 4 模型 | 是 | +| 聊天补全 | 是 | +| 图像生成 | 是 | +| 音乐生成 | 是 | +| 文本转语音 | 是 | +| 实时语音 | 是(Google Live API) | +| 图像理解 | 是 | +| 音频转写 | 是 | +| 视频理解 | 是 | +| 网页搜索(Grounding) | 是 | +| 思考/推理 | 是(Gemini 2.5+ / Gemini 3+) | +| Gemma 4 模型 | 是 | -Gemini 3 模型使用 `thinkingLevel`,而不是 `thinkingBudget`。OpenClaw 会将 -Gemini 3、Gemini 3.1 以及 `gemini-*-latest` 别名的推理控制映射到 -`thinkingLevel`,从而让默认/低延迟运行不会发送被禁用的 -`thinkingBudget` 值。 +Gemini 3 模型使用 `thinkingLevel`,而不是 `thinkingBudget`。OpenClaw 会将 Gemini 3、Gemini 3.1 和 `gemini-*-latest` 别名的推理控制映射到 `thinkingLevel`,这样默认/低延迟运行就不会发送被禁用的 `thinkingBudget` 值。 -Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持 thinking 模式。OpenClaw -会将 `thinkingBudget` 重写为 Google 支持的 `thinkingLevel`,以适配 Gemma 4。 -将 thinking 设置为 `off` 会保持 thinking 关闭,而不会映射为 -`MINIMAL`。 +Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持思考模式。OpenClaw 会将 `thinkingBudget` 重写为 Google 支持的 `thinkingLevel` 用于 Gemma 4。将 thinking 设置为 `off` 时,会保持禁用思考,而不是映射为 `MINIMAL`。 -## 图片生成 +## 图像生成 -内置的 `google` 图片生成提供商默认使用 -`google/gemini-3.1-flash-image-preview`。 +内置的 `google` 图像生成提供商默认使用 `google/gemini-3.1-flash-image-preview`。 - 也支持 `google/gemini-3-pro-image-preview` -- 生成:每次请求最多 4 张图片 -- 编辑模式:已启用,最多支持 5 张输入图片 +- 生成:每次请求最多 4 张图像 +- 编辑模式:已启用,最多支持 5 张输入图像 - 几何控制:`size`、`aspectRatio` 和 `resolution` -要将 Google 设为默认图片提供商: +要将 Google 用作默认图像提供商: ```json5 { @@ -183,20 +168,19 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持 thinking 模式。OpenClaw ``` -共享工具参数、提供商选择和故障切换行为请参见 [图片生成](/zh-CN/tools/image-generation)。 +有关共享工具参数、提供商选择和故障切换行为,请参阅 [Image Generation](/zh-CN/tools/image-generation)。 ## 视频生成 -内置的 `google` 插件还会通过共享的 -`video_generate` 工具注册视频生成。 +内置的 `google` 插件还通过共享的 `video_generate` 工具注册了视频生成功能。 - 默认视频模型:`google/veo-3.1-fast-generate-preview` -- 模式:文本生成视频、图片生成视频,以及单视频参考流程 +- 模式:文生视频、图生视频和单视频参考流程 - 支持 `aspectRatio`、`resolution` 和 `audio` - 当前时长限制:**4 到 8 秒** -要将 Google 设为默认视频提供商: +要将 Google 用作默认视频提供商: ```json5 { @@ -211,22 +195,21 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持 thinking 模式。OpenClaw ``` -共享工具参数、提供商选择和故障切换行为请参见 [视频生成](/zh-CN/tools/video-generation)。 +有关共享工具参数、提供商选择和故障切换行为,请参阅 [Video Generation](/zh-CN/tools/video-generation)。 ## 音乐生成 -内置的 `google` 插件还会通过共享的 -`music_generate` 工具注册音乐生成。 +内置的 `google` 插件还通过共享的 `music_generate` 工具注册了音乐生成功能。 - 默认音乐模型:`google/lyria-3-clip-preview` - 也支持 `google/lyria-3-pro-preview` -- 提示控制:`lyrics` 和 `instrumental` -- 输出格式:默认 `mp3`,而 `google/lyria-3-pro-preview` 还支持 `wav` -- 参考输入:最多 10 张图片 -- 基于会话的运行会通过共享任务/状态流程进行分离,包括 `action: "status"` +- 提示词控制:`lyrics` 和 `instrumental` +- 输出格式:默认 `mp3`,另外在 `google/lyria-3-pro-preview` 上还支持 `wav` +- 参考输入:最多 10 张图像 +- 基于会话的运行会通过共享的任务/状态流程分离执行,其中包括 `action: "status"` -要将 Google 设为默认音乐提供商: +要将 Google 用作默认音乐提供商: ```json5 { @@ -241,20 +224,19 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持 thinking 模式。OpenClaw ``` -共享工具参数、提供商选择和故障切换行为请参见 [音乐生成](/zh-CN/tools/music-generation)。 +有关共享工具参数、提供商选择和故障切换行为,请参阅 [Music Generation](/zh-CN/tools/music-generation)。 ## 文本转语音 -内置的 `google` 语音提供商通过 -`gemini-3.1-flash-tts-preview` 使用 Gemini API TTS 路径。 +内置的 `google` 语音提供商通过 `gemini-3.1-flash-tts-preview` 使用 Gemini API 的 TTS 路径。 - 默认语音:`Kore` -- 身份验证:`messages.tts.providers.google.apiKey`、`models.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` -- 输出:常规 TTS 附件使用 WAV,Talk/电话场景使用 PCM -- 原生语音便笺输出:此 Gemini API 路径不支持,因为 API 返回的是 PCM 而不是 Opus +- 认证:`messages.tts.providers.google.apiKey`、`models.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` +- 输出:常规 TTS 附件为 WAV,Talk/电话场景为 PCM +- 原生语音便笺输出:在这个 Gemini API 路径上不支持,因为 API 返回的是 PCM 而不是 Opus -要将 Google 设为默认 TTS 提供商: +要将 Google 用作默认 TTS 提供商: ```json5 { @@ -273,8 +255,7 @@ Gemma 4 模型(例如 `gemma-4-26b-a4b-it`)支持 thinking 模式。OpenClaw } ``` -Gemini API TTS 接受文本中的表现型方括号音频标签,例如 -`[whispers]` 或 `[laughs]`。为了让这些标签不显示在可见聊天回复中,但仍发送给 TTS,请将它们放在 `[[tts:text]]...[[/tts:text]]` 块中: +Gemini API TTS 接受文本中的方括号表达式音频标签,例如 `[whispers]` 或 `[laughs]`。为了避免这些标签出现在可见的聊天回复中,同时仍将其发送给 TTS,请把它们放在 `[[tts:text]]...[[/tts:text]]` 块内: ```text Here is the clean reply text. @@ -283,23 +264,67 @@ Here is the clean reply text. ``` -受限于 Gemini API 的 Google Cloud Console API 密钥对该 -提供商有效。这不是单独的 Cloud Text-to-Speech API 路径。 +限制为 Gemini API 的 Google Cloud Console API 密钥可用于此提供商。这不是单独的 Cloud Text-to-Speech API 路径。 + + +## 实时语音 + +内置的 `google` 插件注册了一个由 Gemini Live API 提供支持的实时语音提供商,用于 Voice Call 和 Google Meet 等后端音频桥接。 + +| 设置 | 配置路径 | 默认值 | +| --------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| 模型 | `plugins.entries.voice-call.config.realtime.providers.google.model` | `gemini-2.5-flash-native-audio-preview-12-2025` | +| 语音 | `...google.voice` | `Kore` | +| Temperature | `...google.temperature` | (未设置) | +| VAD 起始灵敏度 | `...google.startSensitivity` | (未设置) | +| VAD 结束灵敏度 | `...google.endSensitivity` | (未设置) | +| 静音时长 | `...google.silenceDurationMs` | (未设置) | +| API 密钥 | `...google.apiKey` | 回退到 `models.providers.google.apiKey`、`GEMINI_API_KEY` 或 `GOOGLE_API_KEY` | + +Voice Call 实时配置示例: + +```json5 +{ + plugins: { + entries: { + "voice-call": { + enabled: true, + config: { + realtime: { + enabled: true, + provider: "google", + providers: { + google: { + model: "gemini-2.5-flash-native-audio-preview-12-2025", + voice: "Kore", + }, + }, + }, + }, + }, + }, + }, +} +``` + + +Google Live API 通过 WebSocket 使用双向音频和函数调用。OpenClaw 会将电话/Meet 桥接音频适配到 Gemini 的 PCM Live API 流,并在共享的实时语音契约上保留工具调用。除非你需要调整采样,否则请将 `temperature` 保持未设置;OpenClaw 会省略非正值,因为 Google Live 在 `temperature: 0` 时可能返回只有转写而没有音频的结果。Gemini API 转写在不设置 `languageCodes` 的情况下启用;当前 Google SDK 会拒绝此 API 路径上的语言代码提示。 + + + +Control UI Talk 浏览器会话仍然需要一个具有浏览器 WebRTC 会话实现的实时语音提供商。目前这一条路径是 OpenAI Realtime;Google 提供商用于后端实时桥接。 ## 高级配置 - - 对于直接的 Gemini API 运行(`api: "google-generative-ai"`),OpenClaw - 会将已配置的 `cachedContent` 句柄直接传入 Gemini 请求。 + + 对于直接的 Gemini API 运行(`api: "google-generative-ai"`),OpenClaw 会将已配置的 `cachedContent` 句柄传递给 Gemini 请求。 - - 可使用 - `cachedContent` 或旧版 `cached_content` 配置按模型或全局参数 - - 如果两者同时存在,`cachedContent` 优先 + - 可使用 `cachedContent` 或旧版 `cached_content` 为每个模型或全局参数进行配置 + - 如果两者同时存在,以 `cachedContent` 为准 - 示例值:`cachedContents/prebuilt-context` - - Gemini cache 命中的使用量会从 - 上游的 `cachedContentTokenCount` 规范化为 OpenClaw `cacheRead` + - Gemini 缓存命中用量会从上游的 `cachedContentTokenCount` 规范化为 OpenClaw `cacheRead` ```json5 { @@ -320,32 +345,30 @@ Here is the clean reply text. - 使用 `google-gemini-cli` OAuth 提供商时,OpenClaw 会按如下方式规范化 - CLI JSON 输出: + 使用 `google-gemini-cli` OAuth 提供商时,OpenClaw 会按如下方式规范化 CLI JSON 输出: - 回复文本来自 CLI JSON 的 `response` 字段。 - - 当 CLI 将 `usage` 留空时,使用量会回退到 `stats`。 + - 当 CLI 将 `usage` 留空时,用量会回退到 `stats`。 - `stats.cached` 会被规范化为 OpenClaw `cacheRead`。 - - 如果缺少 `stats.input`,OpenClaw 会从 - `stats.input_tokens - stats.cached` 推导输入 token。 + - 如果缺少 `stats.input`,OpenClaw 会通过 `stats.input_tokens - stats.cached` 推导输入 token 数。 - - 如果 Gateway 网关作为 daemon 运行(launchd/systemd),请确保 `GEMINI_API_KEY` - 对该进程可用(例如放在 `~/.openclaw/.env` 中,或通过 - `env.shellEnv` 提供)。 + + 如果 Gateway 网关以守护进程方式运行(launchd/systemd),请确保 `GEMINI_API_KEY` + 对该进程可用(例如在 `~/.openclaw/.env` 中,或通过 + `env.shellEnv`)。 -## 相关 +## 相关内容 - 如何选择提供商、模型引用和故障切换行为。 + 选择提供商、模型引用和故障切换行为。 - - 共享图片工具参数和提供商选择。 + + 共享图像工具参数和提供商选择。 共享视频工具参数和提供商选择。 diff --git a/docs/zh-CN/tools/capability-cookbook.md b/docs/zh-CN/tools/capability-cookbook.md index adfe4dea6..8ff821665 100644 --- a/docs/zh-CN/tools/capability-cookbook.md +++ b/docs/zh-CN/tools/capability-cookbook.md @@ -1,78 +1,91 @@ --- read_when: - - 添加新的核心能力和插件注册表面 - - 判断代码应放在 core、vendor 插件还是 feature 插件中 + - 添加新的核心能力和插件注册入口面 + - 判断代码应放在核心、供应商插件还是功能插件中 - 为渠道或工具接入新的运行时辅助函数 sidebarTitle: Adding Capabilities summary: 向 OpenClaw 插件系统添加新共享能力的贡献者指南 title: 添加能力(贡献者指南) x-i18n: - generated_at: "2026-04-23T23:04:22Z" + generated_at: "2026-04-24T08:40:04Z" model: gpt-5.4 provider: openai - source_hash: f1e3251b9150c9744d967e91f531dfce01435b13aea3a17088ccd54f2145d14f + source_hash: 864506dd3f61aa64e7c997c9d9e05ce0ad70c80a26a734d4f83b2e80331be4ab source_path: tools/capability-cookbook.md workflow: 15 --- - 这是面向 OpenClaw 核心开发者的**贡献者指南**。如果你正在构建外部插件,请参见[构建插件](/zh-CN/plugins/building-plugins)。 + 这是面向 OpenClaw 核心开发者的**贡献者指南**。如果你正在构建外部插件,请改看 [Building Plugins](/zh-CN/plugins/building-plugins)。 -当 OpenClaw 需要一个新的领域时使用本指南,例如图像生成、视频生成,或未来某个由 vendor 支持的功能领域。 +当 OpenClaw 需要一个新的领域时使用本文,例如图像生成、视频生成,或未来某个由供应商支持的新功能领域。 规则是: - plugin = 所有权边界 - capability = 共享核心契约 -这意味着你不应一开始就把某个 vendor 直接接进渠道或工具。应从定义 capability 开始。 +这意味着你不应一开始就把某个供应商直接接入渠道或工具。应先从定义能力开始。 -## 何时创建 capability +## 何时创建能力 -当以下条件都满足时,创建一个新的 capability: +当以下条件**全部**满足时,创建一个新能力: -1. 不止一个 vendor 有可能实现它 -2. 渠道、工具或 feature 插件应在不关心 vendor 的情况下消费它 -3. core 需要拥有回退、策略、配置或交付行为 +1. 不止一个供应商有可能实现它 +2. 渠道、工具或功能插件应能在不关心供应商的情况下使用它 +3. 核心需要拥有回退、策略、配置或交付行为 -如果这项工作仅限 vendor 且尚不存在共享契约,请先停下来定义契约。 +如果这项工作仅属于某个供应商,且尚不存在共享契约,那就先停下来,先定义契约。 ## 标准顺序 1. 定义带类型的核心契约。 2. 为该契约添加插件注册。 3. 添加共享运行时辅助函数。 -4. 接入一个真实 vendor 插件作为证明。 -5. 将 feature/渠道消费者迁移到运行时辅助函数上。 +4. 接入一个真实的供应商插件作为证明。 +5. 将功能/渠道使用方迁移到运行时辅助函数上。 6. 添加契约测试。 -7. 记录面向操作员的配置和所有权模型。 +7. 记录面向运维者的配置和所有权模型。 ## 各部分应放在哪里 -Core: +核心: - 请求/响应类型 - provider 注册表 + 解析 - 回退行为 - 配置 schema,以及传播到嵌套对象、通配符、数组项和组合节点上的 `title` / `description` 文档元数据 -- 运行时辅助函数表面 +- 运行时辅助函数入口面 -Vendor 插件: +供应商插件: -- vendor API 调用 -- vendor 认证处理 -- vendor 特定的请求规范化 -- capability 实现的注册 +- 供应商 API 调用 +- 供应商鉴权处理 +- 供应商特定的请求规范化 +- 能力实现的注册 -Feature/渠道插件: +功能/渠道插件: -- 调用 `api.runtime.*` 或匹配的 `plugin-sdk/*-runtime` 辅助函数 -- 绝不直接调用 vendor 实现 +- 调用 `api.runtime.*` 或对应的 `plugin-sdk/*-runtime` 辅助函数 +- 绝不直接调用某个供应商实现 + +## Provider 和 Harness 接缝 + +当某个行为属于模型 provider 契约,而不是通用智能体循环时,使用 provider hook。示例包括:在选择传输方式后的 provider 特定请求参数、auth profile 偏好、提示词叠加,以及在模型 / profile 失效切换后的后续回退路由。 + +当某个行为属于执行单轮的运行时时,使用智能体 harness hook。Harness 可以对“成功但不可用”的尝试结果进行分类,例如空响应、仅推理响应或仅规划响应,以便外层模型回退策略决定是否重试。 + +保持这两个接缝都足够窄: + +- 核心拥有重试 / 回退策略 +- provider 插件拥有 provider 特定的请求 / 鉴权 / 路由提示 +- harness 插件拥有运行时特定的尝试分类 +- 第三方插件返回提示,而不是直接修改核心状态 ## 文件清单 -对于一个新的 capability,预计会涉及这些区域: +对于一个新能力,预计会涉及这些区域: - `src//types.ts` - `src//...registry/runtime.ts` @@ -85,39 +98,39 @@ Feature/渠道插件: - `src/plugin-sdk/.ts` - `src/plugin-sdk/-runtime.ts` - 一个或多个内置插件包 -- config/docs/tests +- 配置 / 文档 / 测试 ## 示例:图像生成 -图像生成遵循标准形状: +图像生成遵循标准结构: -1. core 定义 `ImageGenerationProvider` -2. core 暴露 `registerImageGenerationProvider(...)` -3. core 暴露 `runtime.imageGeneration.generate(...)` -4. `openai`、`google`、`fal` 和 `minimax` 插件注册由 vendor 支持的实现 -5. 未来其他 vendor 可以注册同一契约,而无需修改渠道/工具 +1. 核心定义 `ImageGenerationProvider` +2. 核心暴露 `registerImageGenerationProvider(...)` +3. 核心暴露 `runtime.imageGeneration.generate(...)` +4. `openai`、`google`、`fal` 和 `minimax` 插件注册由供应商支持的实现 +5. 未来的供应商可以注册同一契约,而无需更改渠道 / 工具 该配置键与视觉分析路由是分开的: - `agents.defaults.imageModel` = 分析图像 - `agents.defaults.imageGenerationModel` = 生成图像 -请保持二者分离,以便让回退和策略保持明确。 +请保持两者分离,以便让回退和策略保持明确。 ## 评审清单 -在交付新的 capability 之前,请确认: +在发布新能力之前,确认: -- 没有任何渠道/工具直接导入 vendor 代码 +- 没有渠道 / 工具直接导入供应商代码 - 运行时辅助函数是共享路径 -- 至少有一个契约测试断言了内置所有权 -- 配置文档命名了新的模型/配置键 +- 至少有一个契约测试断言内置所有权 +- 配置文档明确写出新的模型 / 配置键 - 插件文档解释了所有权边界 -如果某个 PR 跳过 capability 层,直接把 vendor 行为硬编码进渠道/工具中,请退回该 PR,并先定义契约。 +如果某个 PR 跳过能力层,直接把供应商行为硬编码进渠道 / 工具,应将其打回,并先定义契约。 ## 相关内容 -- [插件](/zh-CN/tools/plugin) -- [创建 Skills](/zh-CN/tools/creating-skills) -- [工具和插件](/zh-CN/tools) +- [Plugin](/zh-CN/tools/plugin) +- [Creating skills](/zh-CN/tools/creating-skills) +- [Tools and plugins](/zh-CN/tools) diff --git a/docs/zh-CN/tools/plugin.md b/docs/zh-CN/tools/plugin.md index b73847cf1..036d80950 100644 --- a/docs/zh-CN/tools/plugin.md +++ b/docs/zh-CN/tools/plugin.md @@ -7,15 +7,15 @@ sidebarTitle: Install and Configure summary: 安装、配置和管理 OpenClaw 插件 title: 插件 x-i18n: - generated_at: "2026-04-24T05:42:16Z" + generated_at: "2026-04-24T08:40:03Z" model: gpt-5.4 provider: openai - source_hash: a93114ddb312552f4c321b6e318f3e19810cf5059dd0c68fde93da41936566b8 + source_hash: 83ab1218d6677ad518a4991ca546d55eed9648e1fa92b76b7433ecd5df569e28 source_path: tools/plugin.md workflow: 15 --- -插件通过新增能力来扩展 OpenClaw:渠道、模型提供商、工具、skills、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等。有些插件是**核心**插件(随 OpenClaw 一起发布),另一些是**外部**插件(由社区发布到 npm)。 +插件通过新增能力来扩展 OpenClaw:渠道、模型提供商、智能体 harness、工具、技能、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等。有些插件是 **核心** 插件(随 OpenClaw 一起发布),另一些则是 **外部** 插件(由社区在 npm 上发布)。 ## 快速开始 @@ -28,10 +28,10 @@ x-i18n: ```bash - # 从 npm + # From npm openclaw plugins install @openclaw/voice-call - # 从本地目录或归档文件 + # From a local directory or archive openclaw plugins install ./my-plugin openclaw plugins install ./my-plugin.tgz ``` @@ -43,12 +43,12 @@ x-i18n: openclaw gateway restart ``` - 然后在你的配置文件中,通过 `plugins.entries.\.config` 进行配置。 + 然后在你的配置文件中通过 `plugins.entries.\.config` 进行配置。 -如果你更喜欢原生聊天方式控制,请启用 `commands.plugins: true` 并使用: +如果你更喜欢聊天原生的控制方式,可启用 `commands.plugins: true` 并使用: ```text /plugin install clawhub:@openclaw/voice-call @@ -56,62 +56,72 @@ x-i18n: /plugin enable voice-call ``` -安装路径使用与 CLI 相同的解析器:本地路径/归档文件、显式 `clawhub:`,或裸包规范(优先 ClawHub,然后回退到 npm)。 +安装路径使用与 CLI 相同的解析器:本地路径/归档文件、显式 +`clawhub:`,或裸包规范(先 ClawHub,后回退到 npm)。 -如果配置无效,安装通常会以失败并阻止继续的方式结束,并引导你使用 `openclaw doctor --fix`。唯一的恢复例外是一个较窄的内置插件重装路径,适用于选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件。 +如果配置无效,安装通常会以安全失败方式终止,并提示你运行 +`openclaw doctor --fix`。唯一的恢复例外是一个针对内置插件的有限重装路径, +适用于选择加入 +`openclaw.install.allowInvalidConfigRecovery` +的插件。 -打包后的 OpenClaw 安装不会急切安装每个内置插件的运行时依赖树。当一个由 OpenClaw 拥有的内置插件因插件配置、旧版渠道配置或默认启用的清单而处于活动状态时,启动过程只会在导入该插件之前修复该插件声明的运行时依赖。外部插件和自定义加载路径仍然必须通过 `openclaw plugins install` 安装。 +已打包的 OpenClaw 安装不会急切安装每个内置插件的全部运行时依赖树。 +当某个 OpenClaw 自带的内置插件因插件配置、旧版渠道配置或默认启用的清单而处于活跃状态时, +启动过程只会在导入该插件之前修复它声明的运行时依赖。 +外部插件和自定义加载路径仍然必须通过 +`openclaw plugins install` +进行安装。 ## 插件类型 OpenClaw 可识别两种插件格式: -| 格式 | 工作方式 | 示例 | -| ---------- | ------------------------------------------------------------------ | ------------------------------------------------------ | -| **原生** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 软件包 | -| **Bundle** | 与 Codex/Claude/Cursor 兼容的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` | +| 格式 | 工作方式 | 示例 | +| ---------- | ---------------------------------------------------------- | ------------------------------------------------------ | +| **原生** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 | +| **Bundle** | 与 Codex/Claude/Cursor 兼容的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` | -两者都会显示在 `openclaw plugins list` 中。有关 bundle 的详细信息,请参阅 [Plugin Bundles](/zh-CN/plugins/bundles)。 +两者都会显示在 `openclaw plugins list` 中。有关 Bundle 的详细信息,请参阅 [Plugin Bundles](/zh-CN/plugins/bundles)。 -如果你要编写原生插件,请从 [Building Plugins](/zh-CN/plugins/building-plugins) +如果你正在编写原生插件,请从 [Building Plugins](/zh-CN/plugins/building-plugins) 和 [插件 SDK 概览](/zh-CN/plugins/sdk-overview) 开始。 ## 官方插件 ### 可安装(npm) -| 插件 | 软件包 | 文档 | -| --------------- | ---------------------- | ------------------------------------ | -| Matrix | `@openclaw/matrix` | [Matrix](/zh-CN/channels/matrix) | -| Microsoft Teams | `@openclaw/msteams` | [Microsoft Teams](/zh-CN/channels/msteams) | -| Nostr | `@openclaw/nostr` | [Nostr](/zh-CN/channels/nostr) | -| Voice Call | `@openclaw/voice-call` | [Voice Call](/zh-CN/plugins/voice-call) | -| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) | -| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) | +| 插件 | 包 | 文档 | +| ---------------- | ---------------------- | ------------------------------------ | +| Matrix | `@openclaw/matrix` | [Matrix](/zh-CN/channels/matrix) | +| Microsoft Teams | `@openclaw/msteams` | [Microsoft Teams](/zh-CN/channels/msteams) | +| Nostr | `@openclaw/nostr` | [Nostr](/zh-CN/channels/nostr) | +| Voice Call | `@openclaw/voice-call` | [Voice Call](/zh-CN/plugins/voice-call) | +| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) | +| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) | ### 核心(随 OpenClaw 一起发布) - `anthropic`, `byteplus`, `cloudflare-ai-gateway`, `github-copilot`, `google`, - `huggingface`, `kilocode`, `kimi-coding`, `minimax`, `mistral`, `qwen`, - `moonshot`, `nvidia`, `openai`, `opencode`, `opencode-go`, `openrouter`, - `qianfan`, `synthetic`, `together`, `venice`, - `vercel-ai-gateway`, `volcengine`, `xiaomi`, `zai` + `anthropic`、`byteplus`、`cloudflare-ai-gateway`、`github-copilot`、`google`、 + `huggingface`、`kilocode`、`kimi-coding`、`minimax`、`mistral`、`qwen`、 + `moonshot`、`nvidia`、`openai`、`opencode`、`opencode-go`、`openrouter`、 + `qianfan`、`synthetic`、`together`、`venice`、 + `vercel-ai-gateway`、`volcengine`、`xiaomi`、`zai` - - `memory-core` — 内置内存搜索(通过 `plugins.slots.memory` 默认启用) - - `memory-lancedb` — 按需安装的长期记忆,带自动召回/捕获(设置 `plugins.slots.memory = "memory-lancedb"`) + - `memory-core` — 内置的 Memory 搜索(默认通过 `plugins.slots.memory`) + - `memory-lancedb` — 按需安装的长期 Memory,支持自动召回/捕获(设置 `plugins.slots.memory = "memory-lancedb"`) - `elevenlabs`, `microsoft` + `elevenlabs`、`microsoft` - - `browser` — 用于浏览器工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、浏览器运行时以及默认浏览器控制服务的内置浏览器插件(默认启用;替换前请先禁用) - - `copilot-proxy` — VS Code Copilot Proxy 桥接器(默认禁用) + - `browser` — 用于 browser 工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、browser 运行时以及默认 browser 控制服务的内置 browser 插件(默认启用;在替换它之前请先禁用) + - `copilot-proxy` — VS Code Copilot Proxy 桥接(默认禁用) @@ -133,30 +143,32 @@ OpenClaw 可识别两种插件格式: } ``` -| 字段 | 描述 | +| 字段 | 说明 | | ---------------- | --------------------------------------------------------- | -| `enabled` | 主开关(默认:`true`) | -| `allow` | 插件允许列表(可选) | -| `deny` | 插件拒绝列表(可选;拒绝优先) | -| `load.paths` | 额外的插件文件/目录 | -| `slots` | 独占插槽选择器(例如 `memory`、`contextEngine`) | -| `entries.\` | 每个插件的开关 + 配置 | +| `enabled` | 主开关(默认:`true`) | +| `allow` | 插件允许列表(可选) | +| `deny` | 插件拒绝列表(可选;拒绝优先) | +| `load.paths` | 额外的插件文件/目录 | +| `slots` | 独占槽位选择器(例如 `memory`、`contextEngine`) | +| `entries.\` | 每个插件的开关 + 配置 | -配置更改**需要重启 Gateway 网关**。如果 Gateway 网关正在以启用配置监听 + 进程内重启的方式运行(默认的 `openclaw gateway` 路径),那么在配置写入完成后,通常会自动在稍后执行重启。 +配置更改 **需要重启 Gateway 网关**。如果 Gateway 网关正在以启用配置监听和进程内重启的方式运行 +(默认的 `openclaw gateway` 路径),那么在配置写入完成后, +通常会自动稍后执行该重启。 - **已禁用**:插件存在,但启用规则将其关闭。配置会被保留。 - - **缺失**:配置引用了某个插件 id,但设备发现未找到该插件。 - - **无效**:插件存在,但其配置不匹配声明的 schema。 + - **缺失**:配置引用了某个插件 id,但在发现过程中未找到该插件。 + - **无效**:插件存在,但其配置与声明的 schema 不匹配。 -## 发现顺序和优先级 +## 发现与优先级 -OpenClaw 按以下顺序扫描插件(先匹配者优先): +OpenClaw 按以下顺序扫描插件(先匹配者生效): - `plugins.load.paths` —— 显式文件或目录路径。 + `plugins.load.paths` — 显式文件或目录路径。 @@ -168,7 +180,7 @@ OpenClaw 按以下顺序扫描插件(先匹配者优先): - 随 OpenClaw 一起发布。很多默认启用(模型提供商、语音)。 + 随 OpenClaw 一起发布。许多插件默认启用(模型提供商、语音)。 其他插件则需要显式启用。 @@ -178,61 +190,63 @@ OpenClaw 按以下顺序扫描插件(先匹配者优先): - `plugins.enabled: false` 会禁用所有插件 - `plugins.deny` 始终优先于 allow - `plugins.entries.\.enabled: false` 会禁用该插件 -- 来自工作区的插件**默认禁用**(必须显式启用) +- 来自工作区的插件 **默认禁用**(必须显式启用) - 内置插件遵循内建的默认启用集合,除非被覆盖 -- 独占插槽可以强制启用该插槽中被选中的插件 -- 某些内置的可选加入插件会在配置命名某个由插件拥有的表面时自动启用,例如提供商模型引用、渠道配置或 harness 运行时 -- OpenAI 系列的 Codex 路由保持独立的插件边界: +- 独占槽位可强制启用为该槽位选中的插件 +- 某些选择加入的内置插件会在配置命名了某个 + 由插件拥有的表面时自动启用,例如提供商模型引用、渠道配置或 harness + 运行时 +- OpenAI 家族的 Codex 路由保持独立的插件边界: `openai-codex/*` 属于 OpenAI 插件,而内置的 Codex app-server 插件则通过 `embeddedHarness.runtime: "codex"` 或旧版 `codex/*` 模型引用来选择 -## 插件 slots(独占类别) +## 插件槽位(独占类别) -某些类别是独占的(一次只能有一个处于活动状态): +某些类别是独占的(同一时间只能激活一个): ```json5 { plugins: { slots: { - memory: "memory-core", // 或使用 "none" 进行禁用 - contextEngine: "legacy", // 或某个插件 id + memory: "memory-core", // or "none" to disable + contextEngine: "legacy", // or a plugin id }, }, } ``` -| 插槽 | 控制内容 | 默认值 | -| --------------- | --------------------- | ------------------- | -| `memory` | 活动中的 Memory 插件 | `memory-core` | -| `contextEngine` | 活动中的上下文引擎 | `legacy`(内置) | +| 槽位 | 控制内容 | 默认值 | +| ---------------- | -------------------- | ------------------- | +| `memory` | 活跃的 Memory 插件 | `memory-core` | +| `contextEngine` | 活跃的上下文引擎 | `legacy`(内建) | ## CLI 参考 ```bash -openclaw plugins list # 紧凑清单 -openclaw plugins list --enabled # 仅显示已加载的插件 +openclaw plugins list # 精简清单 +openclaw plugins list --enabled # 仅显示已加载插件 openclaw plugins list --verbose # 每个插件的详细信息行 openclaw plugins list --json # 机器可读清单 openclaw plugins inspect # 深度详情 openclaw plugins inspect --json # 机器可读 -openclaw plugins inspect --all # 全局表格 +openclaw plugins inspect --all # 全部插件表格 openclaw plugins info # inspect 别名 openclaw plugins doctor # 诊断 -openclaw plugins install # 安装(优先 ClawHub,然后 npm) +openclaw plugins install # 安装(先 ClawHub,后 npm) openclaw plugins install clawhub: # 仅从 ClawHub 安装 openclaw plugins install --force # 覆盖现有安装 openclaw plugins install # 从本地路径安装 openclaw plugins install -l # 链接(不复制),用于开发 openclaw plugins install --marketplace openclaw plugins install --marketplace https://github.com// -openclaw plugins install --pin # 记录精确解析后的 npm 规范 +openclaw plugins install --pin # 记录精确解析后的 npm spec openclaw plugins install --dangerously-force-unsafe-install openclaw plugins update # 更新单个插件 openclaw plugins update --dangerously-force-unsafe-install openclaw plugins update --all # 更新全部 -openclaw plugins uninstall # 删除配置/安装记录 +openclaw plugins uninstall # 移除配置/安装记录 openclaw plugins uninstall --keep-files openclaw plugins marketplace list openclaw plugins marketplace list --json @@ -241,39 +255,57 @@ openclaw plugins enable openclaw plugins disable ``` -内置插件随 OpenClaw 一起发布。很多默认启用(例如内置模型提供商、内置语音提供商以及内置浏览器插件)。其他内置插件仍然需要 `openclaw plugins enable `。 +内置插件随 OpenClaw 一起发布。许多插件默认启用(例如 +内置模型提供商、内置语音提供商以及内置 browser +插件)。其他内置插件仍然需要执行 `openclaw plugins enable `。 -`--force` 会原地覆盖现有已安装插件或 hook 包。对于受跟踪的 npm -插件的常规升级,请使用 `openclaw plugins update `。它不支持与 `--link` 一起使用,因为后者会复用源路径,而不是复制到受管理的安装目标。 +`--force` 会原地覆盖已安装的现有插件或 hook 包。对于已跟踪 npm +插件的常规升级,请使用 `openclaw plugins update `。 +它不支持与 `--link` 一起使用,因为后者会复用源路径, +而不是复制到受管理的安装目标。 -当 `plugins.allow` 已经设置时,`openclaw plugins install` 会在启用插件之前先将已安装的插件 id 添加到该允许列表中,因此插件在重启后可以立即加载。 +当 `plugins.allow` 已经设置时,`openclaw plugins install` 会在启用插件之前 +将已安装插件的 id 添加到该允许列表中,因此重启后即可立即加载。 -`openclaw plugins update ` 适用于受跟踪的安装。传入带 dist-tag 或精确版本的 npm 包规范时,会将该包名解析回受跟踪的插件记录,并记录新的规范以供后续更新。传入不带版本的包名时,会将一个精确固定版本的安装移回注册表的默认发布线。如果已安装的 npm 插件已经匹配解析后的版本和记录的工件标识,OpenClaw 会跳过更新,而不会下载、重新安装或重写配置。 +`openclaw plugins update ` 适用于已跟踪的安装。 +传入带有 dist-tag 或精确版本的 npm 包 spec 时,会将包名解析回已跟踪的插件记录, +并记录新的 spec 以供后续更新使用。 +传入不带版本的包名时,会将精确固定版本的安装移回 +registry 的默认发布线。如果已安装的 npm 插件已经与解析后的版本和记录的制品标识一致, +OpenClaw 会跳过更新,而不会下载、重装或重写配置。 -`--pin` 仅适用于 npm。它不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 来源元数据,而不是 npm 规范。 +`--pin` 仅适用于 npm。它不支持与 `--marketplace` 一起使用,因为 +marketplace 安装会持久化 marketplace 来源元数据,而不是 npm spec。 -`--dangerously-force-unsafe-install` 是用于处理内置危险代码扫描器误报的紧急覆盖开关。它允许插件安装和插件更新在遇到内置 `critical` 发现后继续进行,但仍不会绕过插件 `before_install` 策略阻止或扫描失败阻止。 +`--dangerously-force-unsafe-install` 是一个紧急兜底覆盖选项,用于处理内置危险代码扫描器的误报。 +它允许插件安装和插件更新在遇到内置 `critical` 发现后继续进行, +但仍然不会绕过插件 `before_install` 策略阻止或扫描失败阻止。 -这个 CLI 标志仅适用于插件安装/更新流程。由 Gateway 网关支持的 skill 依赖安装则改用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是独立的 ClawHub skill 下载/安装流程。 +这个 CLI 标志仅适用于插件安装/更新流程。由 Gateway 网关支持的 Skills +依赖安装则使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖项,而 +`openclaw skills install` 仍然是独立的 ClawHub +技能下载/安装流程。 -兼容的 bundle 会参与同一套插件 list/inspect/enable/disable -流程。当前运行时支持包括 bundle skills、Claude command-skills、 -Claude `settings.json` 默认值、Claude `.lsp.json` 以及清单声明的 +兼容的 Bundle 会参与相同的插件 list/inspect/enable/disable +流程。当前运行时支持包括 Bundle Skills、Claude command-skills、 +Claude `settings.json` 默认值、Claude `.lsp.json` 以及由清单声明的 `lspServers` 默认值、Cursor command-skills,以及兼容的 Codex hook 目录。 -`openclaw plugins inspect ` 还会报告已检测到的 bundle 能力,以及针对由 bundle 支持的插件所支持或不受支持的 MCP 和 LSP 服务器条目。 +`openclaw plugins inspect ` 还会报告已检测到的 Bundle 能力,以及 +由 Bundle 支持的插件中受支持或不受支持的 MCP 和 LSP server 条目。 -Marketplace 来源可以是来自 -`~/.claude/plugins/known_marketplaces.json` 的 Claude 已知 marketplace 名称、本地 marketplace 根目录或 +Marketplace 来源可以是 Claude 已知 marketplace 名称(来自 +`~/.claude/plugins/known_marketplaces.json`)、本地 marketplace 根目录或 `marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 -URL,或 git URL。对于远程 marketplace,插件条目必须保留在已克隆的 marketplace 仓库内部,并且只能使用相对路径来源。 +URL,或 git URL。对于远程 marketplace,插件条目必须保留在已克隆的 +marketplace 仓库内,并且只能使用相对路径来源。 有关完整详情,请参阅 [`openclaw plugins` CLI 参考](/zh-CN/cli/plugins)。 ## 插件 API 概览 -原生插件会导出一个入口对象,并公开 `register(api)`。较旧的 +原生插件会导出一个入口对象,该对象暴露 `register(api)`。较旧的 插件仍可能使用 `activate(api)` 作为旧版别名,但新插件应使用 `register`。 @@ -295,46 +327,48 @@ export default definePluginEntry({ }); ``` -OpenClaw 会加载该入口对象,并在插件激活期间调用 `register(api)`。加载器仍会对旧插件回退到 `activate(api)`,但内置插件和新的外部插件应将 `register` 视为公共契约。 +OpenClaw 会加载该入口对象,并在插件激活期间调用 `register(api)`。 +对于旧插件,加载器仍会回退到 `activate(api)`, +但内置插件和新的外部插件应将 `register` 视为公共契约。 常见的注册方法: -| 方法 | 注册内容 | +| 方法 | 注册内容 | | --------------------------------------- | --------------------------- | -| `registerProvider` | 模型提供商(LLM) | -| `registerChannel` | 聊天渠道 | -| `registerTool` | 智能体工具 | -| `registerHook` / `on(...)` | 生命周期 hook | -| `registerSpeechProvider` | 文本转语音 / STT | -| `registerRealtimeTranscriptionProvider` | 流式 STT | -| `registerRealtimeVoiceProvider` | 双工实时语音 | -| `registerMediaUnderstandingProvider` | 图像/音频分析 | -| `registerImageGenerationProvider` | 图像生成 | -| `registerMusicGenerationProvider` | 音乐生成 | -| `registerVideoGenerationProvider` | 视频生成 | -| `registerWebFetchProvider` | 网页抓取 / 抓取提供商 | -| `registerWebSearchProvider` | 网页搜索 | -| `registerHttpRoute` | HTTP 端点 | -| `registerCommand` / `registerCli` | CLI 命令 | -| `registerContextEngine` | 上下文引擎 | -| `registerService` | 后台服务 | +| `registerProvider` | 模型提供商(LLM) | +| `registerChannel` | 聊天渠道 | +| `registerTool` | 智能体工具 | +| `registerHook` / `on(...)` | 生命周期 hook | +| `registerSpeechProvider` | 文本转语音 / STT | +| `registerRealtimeTranscriptionProvider` | 流式 STT | +| `registerRealtimeVoiceProvider` | 双向实时语音 | +| `registerMediaUnderstandingProvider` | 图像/音频分析 | +| `registerImageGenerationProvider` | 图像生成 | +| `registerMusicGenerationProvider` | 音乐生成 | +| `registerVideoGenerationProvider` | 视频生成 | +| `registerWebFetchProvider` | 网页抓取 / 爬取提供商 | +| `registerWebSearchProvider` | 网页搜索 | +| `registerHttpRoute` | HTTP 端点 | +| `registerCommand` / `registerCli` | CLI 命令 | +| `registerContextEngine` | 上下文引擎 | +| `registerService` | 后台服务 | -带类型生命周期 hook 的 guard 行为: +类型化生命周期 hook 的 hook guard 行为: -- `before_tool_call`:`{ block: true }` 是终止性的;较低优先级的处理程序会被跳过。 -- `before_tool_call`:`{ block: false }` 是空操作,不会清除更早的 block。 -- `before_install`:`{ block: true }` 是终止性的;较低优先级的处理程序会被跳过。 -- `before_install`:`{ block: false }` 是空操作,不会清除更早的 block。 -- `message_sending`:`{ cancel: true }` 是终止性的;较低优先级的处理程序会被跳过。 -- `message_sending`:`{ cancel: false }` 是空操作,不会清除更早的 cancel。 +- `before_tool_call`:`{ block: true }` 为终止结果;会跳过更低优先级的处理程序。 +- `before_tool_call`:`{ block: false }` 为 no-op,不会清除更早的 block。 +- `before_install`:`{ block: true }` 为终止结果;会跳过更低优先级的处理程序。 +- `before_install`:`{ block: false }` 为 no-op,不会清除更早的 block。 +- `message_sending`:`{ cancel: true }` 为终止结果;会跳过更低优先级的处理程序。 +- `message_sending`:`{ cancel: false }` 为 no-op,不会清除更早的 cancel。 有关完整的类型化 hook 行为,请参阅 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。 ## 相关内容 - [Building Plugins](/zh-CN/plugins/building-plugins) — 创建你自己的插件 -- [Plugin Bundles](/zh-CN/plugins/bundles) — Codex/Claude/Cursor bundle 兼容性 +- [Plugin Bundles](/zh-CN/plugins/bundles) — Codex/Claude/Cursor Bundle 兼容性 - [Plugin Manifest](/zh-CN/plugins/manifest) — 清单 schema - [Registering Tools](/zh-CN/plugins/building-plugins#registering-agent-tools) — 在插件中添加智能体工具 -- [Plugin Internals](/zh-CN/plugins/architecture) — 能力模型和加载流水线 +- [Plugin Internals](/zh-CN/plugins/architecture) — 能力模型和加载管线 - [Community Plugins](/zh-CN/plugins/community) — 第三方列表 diff --git a/docs/zh-CN/web/control-ui.md b/docs/zh-CN/web/control-ui.md index d42af1ccc..e21d8e656 100644 --- a/docs/zh-CN/web/control-ui.md +++ b/docs/zh-CN/web/control-ui.md @@ -5,10 +5,10 @@ read_when: summary: Gateway 网关的基于浏览器的控制 UI(聊天、节点、配置) title: 控制 UI x-i18n: - generated_at: "2026-04-24T04:37:02Z" + generated_at: "2026-04-24T08:40:03Z" model: gpt-5.4 provider: openai - source_hash: 2ad0d0cef7d842eddf665ba50f37403df258b17d4c072d22a30d1bc3830dc467 + source_hash: c84a74e20d6c8829168025830ff4ec8f650f10f72fcaed7c8d2f5d92ab98d616 source_path: web/control-ui.md workflow: 15 --- @@ -18,7 +18,7 @@ Control UI 是一个由 Gateway 网关提供的小型 **Vite + Lit** 单页应 - 默认:`http://:18789/` - 可选前缀:设置 `gateway.controlUi.basePath`(例如 `/openclaw`) -它会在同一端口上**直接与 Gateway WebSocket 通信**。 +它会在同一端口上**直接连接到 Gateway WebSocket**。 ## 快速打开(本地) @@ -26,22 +26,22 @@ Control UI 是一个由 Gateway 网关提供的小型 **Vite + Lit** 单页应 - [http://127.0.0.1:18789/](http://127.0.0.1:18789/)(或 [http://localhost:18789/](http://localhost:18789/)) -如果页面加载失败,请先启动 Gateway 网关:`openclaw gateway`。 +如果页面无法加载,请先启动 Gateway 网关:`openclaw gateway`。 认证会在 WebSocket 握手期间通过以下方式提供: - `connect.params.auth.token` - `connect.params.auth.password` -- 当 `gateway.auth.allowTailscale: true` 时使用 Tailscale Serve 身份头 -- 当 `gateway.auth.mode: "trusted-proxy"` 时使用受信任代理身份头 +- 当 `gateway.auth.allowTailscale: true` 时,使用 Tailscale Serve 身份标头 +- 当 `gateway.auth.mode: "trusted-proxy"` 时,使用受信任代理身份标头 -仪表板设置面板会为当前浏览器标签页会话保存一个 token 和所选的 gateway URL;密码不会被持久化保存。新手引导通常会在首次连接时为共享密钥认证生成一个 gateway token,但当 `gateway.auth.mode` 为 `"password"` 时,也可以使用密码认证。 +仪表板设置面板会为当前浏览器标签页会话保存一个 token 和所选的 gateway URL;密码不会被持久化保存。新手引导通常会在首次连接时为共享密钥认证生成一个 gateway token,但当 `gateway.auth.mode` 为 `"password"` 时,密码认证也同样可用。 ## 设备配对(首次连接) -当你从新的浏览器或设备连接到 Control UI 时,Gateway 网关会要求进行**一次性配对批准**——即使你位于同一 Tailnet 且设置了 `gateway.auth.allowTailscale: true`。这是防止未经授权访问的一项安全措施。 +当你从新的浏览器或设备连接到 Control UI 时,Gateway 网关会要求进行**一次性配对批准**——即使你位于同一个 Tailnet 上并启用了 `gateway.auth.allowTailscale: true`。这是一项安全措施,用于防止未授权访问。 -**你会看到:** “disconnected (1008): pairing required” +**你会看到:**“disconnected (1008): pairing required” **批准设备的方法:** @@ -53,99 +53,99 @@ openclaw devices list openclaw devices approve ``` -如果浏览器在重试配对时更改了认证详情(角色/作用域/公钥),之前的待处理请求会被替代,并创建新的 `requestId`。批准前请重新运行 `openclaw devices list`。 +如果浏览器在重试配对时更改了认证详情(角色/作用域/公钥),之前的待处理请求会被替代,并创建一个新的 `requestId`。批准前请重新运行 `openclaw devices list`。 -如果浏览器已经完成配对,而你将其权限从只读更改为写入/管理员权限,这会被视为批准升级,而不是静默重连。OpenClaw 会保留旧批准仍然有效,阻止更高权限的重连,并要求你显式批准新的作用域集合。 +如果浏览器已经完成配对,而你将其权限从只读改为写入/管理员权限,这会被视为批准升级,而不是静默重连。OpenClaw 会保持旧批准有效,阻止更高权限的重连,并要求你显式批准新的作用域集合。 -一旦获得批准,该设备会被记住,除非你使用 `openclaw devices revoke --device --role ` 撤销它,否则无需再次批准。有关 token 轮换和撤销,请参见 [Devices CLI](/zh-CN/cli/devices)。 +一旦批准,设备就会被记住,除非你使用 `openclaw devices revoke --device --role ` 撤销它,否则不需要再次批准。有关 token 轮换和撤销,请参见 [Devices CLI](/zh-CN/cli/devices)。 -**注意:** +**说明:** -- 直接的本地 local loopback 浏览器连接(`127.0.0.1` / `localhost`)会被自动批准。 -- Tailnet 和局域网浏览器连接仍然需要显式批准,即使它们来自同一台机器。 -- 每个浏览器配置文件都会生成唯一的设备 ID,因此切换浏览器或清除浏览器数据都需要重新配对。 +- 直接通过本地 local loopback 浏览器连接(`127.0.0.1` / `localhost`)会被自动批准。 +- Tailnet 和 LAN 浏览器连接仍然需要显式批准,即使它们来自同一台机器。 +- 每个浏览器配置文件都会生成唯一的设备 ID,因此切换浏览器或清除浏览器数据都会需要重新配对。 ## 个人身份(浏览器本地) -Control UI 支持每个浏览器一个个人身份(显示名称和头像),会附加到发出的消息上,以便在共享会话中标明归属。它保存在浏览器存储中,仅限当前浏览器配置文件,不会同步到其他设备,也不会在服务器端持久化保存,超出你实际发送消息时的常规转录作者元数据范围。清除站点数据或切换浏览器会将其重置为空。 +Control UI 支持按浏览器设置个人身份(显示名称和头像),会附加到发出的消息上,以便在共享会话中标明来源。它存储在浏览器存储中,作用域仅限当前浏览器配置文件,不会同步到其他设备,也不会在服务端持久化保存;服务端只会在你实际发送的消息中保留正常的消息作者元数据。清除站点数据或切换浏览器会将其重置为空。 ## 运行时配置端点 -Control UI 会从 `\/__openclaw/control-ui-config.json` 获取其运行时设置。该端点受与其余 HTTP 接口相同的 gateway 认证保护:未认证的浏览器无法获取它,成功获取要求具备已有效的 gateway token/密码、Tailscale Serve 身份,或受信任代理身份之一。 +Control UI 会从 ` /__openclaw/control-ui-config.json` 获取其运行时设置。该端点受到与其余 HTTP 接口相同的 gateway 认证保护:未认证的浏览器无法获取它;成功获取需要已有效的 gateway token/密码、Tailscale Serve 身份或受信任代理身份之一。 ## 语言支持 -Control UI 可以在首次加载时根据你的浏览器区域设置进行本地化。若要稍后覆盖它,请打开 **Overview -> Gateway Access -> Language**。语言选择器位于 Gateway Access 卡片中,而不在外观设置下。 +Control UI 可在首次加载时根据你的浏览器语言环境进行本地化。若要稍后覆盖,请打开**Overview -> Gateway Access -> Language**。语言选择器位于 Gateway Access 卡片中,而不在外观设置下。 -- 支持的区域设置:`en`, `zh-CN`, `zh-TW`, `pt-BR`, `de`, `es`, `ja-JP`, `ko`, `fr`, `tr`, `uk`, `id`, `pl`, `th` -- 非英文翻译会在浏览器中按需懒加载。 -- 所选区域设置会保存在浏览器存储中,并在今后访问时重复使用。 -- 缺失的翻译键会回退到英文。 +- 支持的语言环境:`en`, `zh-CN`, `zh-TW`, `pt-BR`, `de`, `es`, `ja-JP`, `ko`, `fr`, `tr`, `uk`, `id`, `pl`, `th` +- 非英语翻译会在浏览器中按需懒加载。 +- 所选语言环境会保存在浏览器存储中,并在以后访问时复用。 +- 缺失的翻译键会回退到英语。 -## 它目前可以做什么 +## 它目前能做什么 - 通过 Gateway WS 与模型聊天(`chat.history`, `chat.send`, `chat.abort`, `chat.inject`) -- 通过 WebRTC 直接从浏览器与 OpenAI Realtime 通话。Gateway 网关使用 `talk.realtime.session` 生成短期有效的 Realtime 客户端密钥;浏览器将麦克风音频直接发送到 OpenAI,并通过 `chat.send` 把 `openclaw_agent_consult` 工具调用中继回去,供已配置的更大型 OpenClaw 模型使用。 +- 通过 WebRTC 在浏览器中直接连接 OpenAI Realtime。Gateway 网关会使用 `talk.realtime.session` 签发一个短期有效的 Realtime 客户端密钥;浏览器会将麦克风音频直接发送给 OpenAI,并通过 `chat.send` 将 `openclaw_agent_consult` 工具调用中继回已配置的更大 OpenClaw 模型。 - 在聊天中流式显示工具调用 + 实时工具输出卡片(智能体事件) -- 渠道:内置渠道以及内置/外部插件渠道的状态、二维码登录和按渠道配置(`channels.status`, `web.login.*`, `config.patch`) -- 实例:在线状态列表 + 刷新(`system-presence`) -- 会话:列表 + 针对每个会话的模型/思考/快速/详细/追踪/推理覆盖项(`sessions.list`, `sessions.patch`) -- Dreams:Dreaming 状态、启用/禁用切换,以及 Dream Diary 阅读器(`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`) +- 渠道:内置以及内置/外部渠道插件的状态、二维码登录和按渠道配置(`channels.status`, `web.login.*`, `config.patch`) +- 实例:在线列表 + 刷新(`system-presence`) +- 会话:列表 + 按会话设置 model/thinking/fast/verbose/trace/reasoning 覆盖(`sessions.list`, `sessions.patch`) +- Dreams:Dreaming 状态、启用/禁用切换和 Dream Diary 阅读器(`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`) - Cron 作业:列出/添加/编辑/运行/启用/禁用 + 运行历史(`cron.*`) -- Skills:状态、启用/禁用、安装、API 密钥更新(`skills.*`) +- Skills:状态、启用/禁用、安装、API key 更新(`skills.*`) - 节点:列表 + 能力上限(`node.list`) - Exec 批准:编辑 gateway 或节点允许列表 + 为 `exec host=gateway/node` 询问策略(`exec.approvals.*`) - 配置:查看/编辑 `~/.openclaw/openclaw.json`(`config.get`, `config.set`) -- 配置:带验证地应用 + 重启(`config.apply`),并唤醒最近活跃的会话 +- 配置:应用并重启,同时执行校验(`config.apply`),并唤醒最后一个活跃会话 - 配置写入包含 base-hash 保护,以防覆盖并发编辑 -- 配置写入(`config.set`/`config.apply`/`config.patch`)还会对提交配置负载中的活跃 SecretRef 解析进行预检;若提交的活跃引用中有未解析项,会在写入前被拒绝 -- 配置 schema + 表单渲染(`config.schema` / `config.schema.lookup`,包括字段 `title` / `description`、匹配的 UI 提示、直接子项摘要、嵌套对象/通配符/数组/组合节点上的文档元数据,以及可用时的插件 + 渠道 schema);仅当快照可以安全地进行原始往返时,Raw JSON 编辑器才可用 -- 如果某个快照无法安全地进行原始往返,Control UI 会强制使用表单模式,并对该快照禁用 Raw 模式 -- Raw JSON 编辑器中的 “Reset to saved” 会保留原始编写的形状(格式、注释、`$include` 布局),而不是重新渲染一个扁平化快照,因此当快照可以安全往返时,外部编辑在重置后仍会保留 -- 结构化 SecretRef 对象值会在表单文本输入中以只读方式呈现,以防意外把对象破坏成字符串 +- 配置写入(`config.set`/`config.apply`/`config.patch`)还会预先检查已提交配置负载中活动 SecretRef 的解析情况;未解析的活动已提交引用会在写入前被拒绝 +- 配置 schema + 表单渲染(`config.schema` / `config.schema.lookup`,包括字段 `title` / `description`、匹配的 UI 提示、直接子项摘要、嵌套对象/通配符/数组/组合节点上的文档元数据,以及在可用时的插件 + 渠道 schema);仅当快照具备安全的原始往返能力时,才提供原始 JSON 编辑器 +- 如果快照无法安全地进行原始往返,Control UI 会强制使用表单模式,并为该快照禁用原始模式 +- 原始 JSON 编辑器中的“Reset to saved”会保留原始编写的结构(格式、注释、`$include` 布局),而不是重新渲染一个扁平化快照,因此当快照可以安全往返时,外部编辑在重置后仍会保留 +- 结构化 SecretRef 对象值会在表单文本输入中以只读方式呈现,以防对象被意外转成字符串并损坏 - 调试:状态/健康/模型快照 + 事件日志 + 手动 RPC 调用(`status`, `health`, `models.list`) -- 日志:带筛选/导出的 gateway 文件日志实时 tail(`logs.tail`) -- 更新:运行包/git 更新 + 重启(`update.run`),并附带重启报告 +- 日志:实时跟踪 gateway 文件日志,支持筛选/导出(`logs.tail`) +- 更新:运行 package/git 更新 + 重启(`update.run`),并附带重启报告 Cron 作业面板说明: -- 对于隔离作业,投递方式默认为公告摘要。如果你希望仅内部运行,可以切换为 none。 -- 选择 announce 时,会显示 channel/target 字段。 -- Webhook 模式使用 `delivery.mode = "webhook"`,并将 `delivery.to` 设为有效的 HTTP(S) webhook URL。 -- 对于主会话作业,可用的投递模式为 webhook 和 none。 -- 高级编辑控件包括运行后删除、清除智能体覆盖、cron 精确/错峰选项、智能体模型/思考覆盖,以及尽力投递切换。 -- 表单验证为内联字段级错误;在修复前,无效值会禁用保存按钮。 -- 设置 `cron.webhookToken` 可发送专用 bearer token;若省略,webhook 将在不带认证头的情况下发送。 -- 已弃用的回退方式:带有 `notify: true` 的旧版已存储作业在迁移前仍可使用 `cron.webhook`。 +- 对于隔离作业,投递方式默认是公告摘要。如果你希望仅内部运行,可以切换为 none。 +- 选择 announce 时会显示 channel/target 字段。 +- Webhook 模式使用 `delivery.mode = "webhook"`,并将 `delivery.to` 设置为有效的 HTTP(S) webhook URL。 +- 对于主会话作业,支持 webhook 和 none 投递模式。 +- 高级编辑控件包括:运行后删除、清除智能体覆盖、cron 精确/错峰选项、智能体 model/thinking 覆盖,以及尽力投递切换。 +- 表单校验为内联方式,带字段级错误;在修复前,无效值会禁用保存按钮。 +- 设置 `cron.webhookToken` 可以发送专用 bearer token;如果省略,则 webhook 发送时不带认证标头。 +- 已弃用的回退方式:仍使用 `notify: true` 存储的旧版作业在迁移前仍可使用 `cron.webhook`。 ## 聊天行为 -- `chat.send` 是**非阻塞**的:它会立即确认并返回 `{ runId, status: "started" }`,响应会通过 `chat` 事件流式传输。 -- 使用相同的 `idempotencyKey` 重新发送时,运行中会返回 `{ status: "in_flight" }`,完成后返回 `{ status: "ok" }`。 -- 出于 UI 安全考虑,`chat.history` 响应有大小限制。当转录条目过大时,Gateway 网关可能会截断较长文本字段、省略较重的元数据块,并用占位符替换超大消息(`[chat.history omitted: message too large]`)。 -- 助手/生成的图片会作为托管媒体引用持久化,并通过经过认证的 Gateway 媒体 URL 返回,因此重新加载时不依赖原始 base64 图像负载仍保留在聊天历史响应中。 -- `chat.history` 还会从可见的助手文本中去除仅用于显示的内联指令标签(例如 `[[reply_to_*]]` 和 `[[audio_as_voice]]`)、纯文本工具调用 XML 负载(包括 `...`、`...`、`...`、`...` 以及被截断的工具调用块),并去除泄露的 ASCII/全角模型控制 token;同时省略那些其全部可见文本仅为精确静默 token `NO_REPLY` / `no_reply` 的助手条目。 -- `chat.inject` 会向会话转录附加一条助手备注,并广播一个 `chat` 事件,用于仅 UI 更新(不会触发智能体运行,也不会投递到渠道)。 -- 聊天头部中的模型和思考选择器会通过 `sessions.patch` 立即更新当前活跃会话;它们是持久的会话覆盖项,而不是仅对单轮发送生效的选项。 -- Talk 模式使用已注册的实时语音提供商。请将 OpenAI 配置为 `talk.provider: "openai"` 并设置 `talk.providers.openai.apiKey`,或复用 Voice Call 的实时提供商配置。浏览器永远不会接收到标准 OpenAI API key;它只会收到临时的 Realtime 客户端密钥。Realtime 会话提示词由 Gateway 网关组装;`talk.realtime.session` 不接受调用方提供的指令覆盖。 -- 在 Chat 输入框中,Talk 控件是麦克风听写按钮旁边的波形按钮。当 Talk 启动时,输入框状态行会显示 `Connecting Talk...`,然后在音频连接时显示 `Talk live`,或在实时工具调用通过 `chat.send` 咨询已配置的更大型模型时显示 `Asking OpenClaw...`。 +- `chat.send` 是**非阻塞**的:它会立即确认并返回 `{ runId, status: "started" }`,响应通过 `chat` 事件流式传输。 +- 使用相同的 `idempotencyKey` 重新发送时,运行中会返回 `{ status: "in_flight" }`,完成后会返回 `{ status: "ok" }`。 +- 出于 UI 安全考虑,`chat.history` 响应有大小限制。当转录条目过大时,Gateway 网关可能会截断较长的文本字段、忽略较重的元数据块,并用占位符替换超大消息(`[chat.history omitted: message too large]`)。 +- 助手/生成的图像会以托管媒体引用形式持久化保存,并通过已认证的 Gateway 网关媒体 URL 返回,因此重新加载不依赖聊天历史响应中保留原始 base64 图像负载。 +- `chat.history` 还会从可见的助手文本中去除仅用于显示的内联指令标签(例如 `[[reply_to_*]]` 和 `[[audio_as_voice]]`)、纯文本工具调用 XML 负载(包括 `...`, `...`, `...`, `...`,以及被截断的工具调用块),并去除泄露的 ASCII/全角模型控制 token,同时省略那些完整可见文本仅为精确静默 token `NO_REPLY` / `no_reply` 的助手条目。 +- `chat.inject` 会向会话转录附加一条助手备注,并广播一个 `chat` 事件用于仅 UI 更新(不会触发智能体运行,也不会投递到渠道)。 +- 聊天头部的 model 和 thinking 选择器会立即通过 `sessions.patch` 更新当前活跃会话;它们是持久化的会话覆盖,而不是仅单轮发送选项。 +- Talk 模式使用已注册的、支持浏览器 WebRTC 会话的实时语音提供商。可通过 `talk.provider: "openai"` 加上 `talk.providers.openai.apiKey` 来配置 OpenAI,或者复用 Voice Call 实时提供商配置。浏览器永远不会收到标准 OpenAI API key;它只会收到临时的 Realtime 客户端密钥。Google Live 实时语音支持后端 Voice Call 和 Google Meet 桥接,但暂不支持此浏览器 WebRTC 路径。Realtime 会话提示由 Gateway 网关组装;`talk.realtime.session` 不接受调用方提供的指令覆盖。 +- 在聊天输入框中,Talk 控件是麦克风听写按钮旁边的波形按钮。Talk 启动时,输入框状态行会显示 `Connecting Talk...`,音频连接后显示 `Talk live`,而当实时工具调用通过 `chat.send` 咨询已配置的更大模型时,则显示 `Asking OpenClaw...`。 - 停止: - 点击 **Stop**(调用 `chat.abort`) - - 当某次运行处于活跃状态时,普通后续消息会进入队列。点击排队消息上的 **Steer** 可将该后续消息注入当前运行轮次。 - - 输入 `/stop`(或独立的中止短语,如 `stop`、`stop action`、`stop run`、`stop openclaw`、`please stop`)可进行带外中止 - - `chat.abort` 支持 `{ sessionKey }`(无需 `runId`),用于中止该会话的所有活跃运行 + - 当某次运行处于活动状态时,普通后续消息会进入队列。点击排队消息上的 **Steer** 可将该后续消息注入当前运行轮次。 + - 输入 `/stop`(或单独的中止短语,如 `stop`、`stop action`、`stop run`、`stop openclaw`、`please stop`)以带外中止 + - `chat.abort` 支持 `{ sessionKey }`(无需 `runId`)以中止该会话的所有活动运行 - 中止后的部分保留: - - 当某次运行被中止时,部分助手文本仍可在 UI 中显示 - - 当存在缓冲输出时,Gateway 网关会将中止时的部分助手文本持久化到转录历史中 - - 持久化条目包含中止元数据,以便转录使用方区分中止部分与正常完成输出 + - 当某次运行被中止时,UI 中仍可能显示部分助手文本 + - 当存在缓冲输出时,Gateway 网关会将中止时的部分助手文本持久化保存到转录历史中 + - 持久化条目包含中止元数据,因此转录消费者可以区分中止的部分内容与正常完成输出 ## 托管嵌入 -助手消息可以通过 `[embed ...]` 简码内联渲染托管网页内容。iframe 沙箱策略由 `gateway.controlUi.embedSandbox` 控制: +助手消息可以通过 `[embed ...]` 短代码内联渲染托管的 Web 内容。iframe 沙箱策略由 `gateway.controlUi.embedSandbox` 控制: - `strict`:禁用托管嵌入中的脚本执行 -- `scripts`:允许交互式嵌入,同时保持源隔离;这是默认值,通常足以支持自包含的浏览器游戏/小部件 -- `trusted`:在 `allow-scripts` 基础上额外添加 `allow-same-origin`,用于那些确实需要更强权限的同站文档 +- `scripts`:允许交互式嵌入,同时保持源隔离;这是默认值,通常足以支持独立的浏览器游戏/小组件 +- `trusted`:在 `allow-scripts` 之上额外添加 `allow-same-origin`,用于有意需要更强权限的同站文档 示例: @@ -159,15 +159,15 @@ Cron 作业面板说明: } ``` -只有在嵌入文档确实需要 same-origin 行为时才使用 `trusted`。对于大多数由智能体生成的游戏和交互式画布,`scripts` 是更安全的选择。 +仅当嵌入文档确实需要同源行为时才使用 `trusted`。对于大多数由智能体生成的游戏和交互式画布,`scripts` 是更安全的选择。 -默认情况下,绝对外部 `http(s)` 嵌入 URL 仍会被阻止。如果你确实希望 `[embed url="https://..."]` 加载第三方页面,请设置 `gateway.controlUi.allowExternalEmbedUrls: true`。 +默认情况下,绝对外部 `http(s)` 嵌入 URL 会继续被阻止。如果你确实想让 `[embed url="https://..."]` 加载第三方页面,请设置 `gateway.controlUi.allowExternalEmbedUrls: true`。 ## Tailnet 访问(推荐) ### 集成式 Tailscale Serve(首选) -让 Gateway 网关保持在 loopback 上,并让 Tailscale Serve 通过 HTTPS 反向代理它: +让 Gateway 网关保持绑定在 loopback 上,并让 Tailscale Serve 通过 HTTPS 代理它: ```bash openclaw gateway --tailscale serve @@ -177,13 +177,9 @@ openclaw gateway --tailscale serve - `https:///`(或你配置的 `gateway.controlUi.basePath`) -默认情况下,当 `gateway.auth.allowTailscale` 为 `true` 时,Control UI/WebSocket Serve 请求可以通过 Tailscale 身份头 -(`tailscale-user-login`)进行认证。OpenClaw 会通过使用 -`tailscale whois` 解析 `x-forwarded-for` 地址并将其与该头匹配来验证身份,并且仅当请求命中 loopback 且携带 Tailscale 的 `x-forwarded-*` 头时才接受这些头。如果你希望即使对于 Serve 流量也要求显式共享密钥凭证,请设置 -`gateway.auth.allowTailscale: false`。然后使用 `gateway.auth.mode: "token"` 或 -`"password"`。 -对于这一路异步 Serve 身份路径,来自同一客户端 IP 和认证作用域的失败认证尝试会在写入速率限制之前被串行化。因此,来自同一浏览器的并发错误重试在第二个请求上可能显示 `retry later`,而不是两个普通不匹配并行竞争。 -无 token 的 Serve 认证假定 gateway 主机是受信任的。如果该主机上可能运行不受信任的本地代码,请要求 token/密码认证。 +默认情况下,当 `gateway.auth.allowTailscale` 为 `true` 时,Control UI/WebSocket Serve 请求可以通过 Tailscale 身份标头(`tailscale-user-login`)进行认证。OpenClaw 会通过 `tailscale whois` 解析 `x-forwarded-for` 地址并将其与该标头匹配来验证身份,并且仅当请求通过 Tailscale 的 `x-forwarded-*` 标头命中 loopback 时才接受这些标头。如果你想即使对于 Serve 流量也要求显式共享密钥凭证,请设置 `gateway.auth.allowTailscale: false`。然后使用 `gateway.auth.mode: "token"` 或 `"password"`。 +对于该异步 Serve 身份路径,来自同一客户端 IP 和相同认证作用域的失败认证尝试会在写入速率限制前被串行化。因此,来自同一浏览器的并发错误重试在第二个请求上可能会显示 `retry later`,而不是两个普通不匹配并行竞争。 +无 token 的 Serve 认证默认假设 gateway 主机是可信的。如果该主机上可能运行不受信任的本地代码,请要求使用 token/密码认证。 ### 绑定到 tailnet + token @@ -195,22 +191,19 @@ openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)" - `http://:18789/`(或你配置的 `gateway.controlUi.basePath`) -将匹配的共享密钥粘贴到 UI 设置中(作为 -`connect.params.auth.token` 或 `connect.params.auth.password` 发送)。 +将匹配的共享密钥粘贴到 UI 设置中(作为 `connect.params.auth.token` 或 `connect.params.auth.password` 发送)。 ## 不安全的 HTTP -如果你通过纯 HTTP 打开仪表板(`http://` 或 `http://`), -浏览器会在**非安全上下文**中运行,并阻止 WebCrypto。默认情况下, -OpenClaw 会**阻止**没有设备身份的 Control UI 连接。 +如果你通过纯 HTTP 打开仪表板(`http://` 或 `http://`),浏览器会运行在**非安全上下文**中,并阻止 WebCrypto。默认情况下,OpenClaw 会**阻止**没有设备身份的 Control UI 连接。 -文档记录的例外情况: +已记录的例外情况: -- 仅限 localhost 的不安全 HTTP 兼容模式,使用 `gateway.controlUi.allowInsecureAuth=true` -- 通过 `gateway.auth.mode: "trusted-proxy"` 成功进行的操作员 Control UI 认证 -- 紧急破窗模式 `gateway.controlUi.dangerouslyDisableDeviceAuth=true` +- 通过 `gateway.controlUi.allowInsecureAuth=true` 启用的仅 localhost 不安全 HTTP 兼容模式 +- 通过 `gateway.auth.mode: "trusted-proxy"` 成功完成的操作员 Control UI 认证 +- 紧急兜底 `gateway.controlUi.dangerouslyDisableDeviceAuth=true` -**推荐修复方式:** 使用 HTTPS(Tailscale Serve)或在本地打开 UI: +**推荐修复方式:**使用 HTTPS(Tailscale Serve)或在本地打开 UI: - `https:///`(Serve) - `http://127.0.0.1:18789/`(在 gateway 主机上) @@ -227,13 +220,13 @@ OpenClaw 会**阻止**没有设备身份的 Control UI 连接。 } ``` -`allowInsecureAuth` 只是一个本地兼容性开关: +`allowInsecureAuth` 只是本地兼容性开关: -- 它允许 localhost 的 Control UI 会话在非安全 HTTP 上下文中在没有设备身份的情况下继续进行。 +- 它允许 localhost Control UI 会话在非安全 HTTP 上下文中无需设备身份即可继续。 - 它不会绕过配对检查。 - 它不会放宽远程(非 localhost)设备身份要求。 -**仅限紧急破窗:** +**仅限紧急兜底:** ```json5 { @@ -245,38 +238,37 @@ OpenClaw 会**阻止**没有设备身份的 Control UI 连接。 } ``` -`dangerouslyDisableDeviceAuth` 会禁用 Control UI 的设备身份检查,是一次严重的安全降级。紧急使用后请尽快恢复。 +`dangerouslyDisableDeviceAuth` 会禁用 Control UI 设备身份检查,这是严重的安全降级。仅在紧急使用后尽快恢复原状。 受信任代理说明: - 成功的 trusted-proxy 认证可以允许**操作员** Control UI 会话在没有设备身份的情况下接入 - 这**不**适用于节点角色的 Control UI 会话 -- 同主机 loopback 反向代理仍然不能满足 trusted-proxy 认证;请参见 - [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth) +- 同主机 loopback 反向代理仍然不能满足 trusted-proxy 认证;参见 [Trusted Proxy Auth](/zh-CN/gateway/trusted-proxy-auth) 有关 HTTPS 设置指导,请参见 [Tailscale](/zh-CN/gateway/tailscale)。 ## 内容安全策略 -Control UI 使用严格的 `img-src` 策略:只允许**同源**资源和 `data:` URL。远程 `http(s)` 和协议相对图片 URL 会被浏览器拒绝,并且不会发起网络请求。 +Control UI 附带了严格的 `img-src` 策略:只允许**同源**资源和 `data:` URL。远程 `http(s)` 和协议相对图片 URL 会被浏览器拒绝,并且不会发起网络请求。 -这在实际中意味着: +这在实际中的含义是: -- 通过相对路径提供的头像和图片(例如 `/avatars/`)仍然可以渲染。 -- 内联 `data:image/...` URL 仍然可以渲染(对协议内负载很有用)。 -- 由渠道元数据输出的远程头像 URL 会在 Control UI 的头像辅助函数中被移除,并替换为内置 logo/badge,因此即使某个渠道被攻陷或是恶意的,也无法强制操作员浏览器发起任意远程图片请求。 +- 在相对路径下提供的头像和图片(例如 `/avatars/`)仍可正常渲染。 +- 内联 `data:image/...` URL 仍可正常渲染(适用于协议内负载)。 +- 由渠道元数据发出的远程头像 URL 会在 Control UI 的头像辅助函数中被剥离,并替换为内置 logo/badge,因此被攻破或恶意的渠道无法强制操作员浏览器发起任意远程图片请求。 你无需做任何更改即可获得此行为——它始终开启,且不可配置。 ## 头像路由认证 -配置了 gateway 认证后,Control UI 的头像端点需要与 API 其余部分相同的 gateway token: +配置了 gateway 认证后,Control UI 头像端点需要与其余 API 相同的 gateway token: - `GET /avatar/` 仅向已认证调用方返回头像图片。`GET /avatar/?meta=1` 在相同规则下返回头像元数据。 -- 对这两个路由的未认证请求都会被拒绝(与同级的 assistant-media 路由一致)。这可以防止头像路由在原本受保护的主机上泄露智能体身份。 -- Control UI 本身在获取头像时会将 gateway token 作为 bearer 头转发,并使用已认证的 blob URL,因此图片仍然可以在仪表板中渲染。 +- 对这两个路由的未认证请求都会被拒绝(与相邻的 assistant-media 路由一致)。这可防止头像路由在其他部分已受保护的主机上泄露智能体身份。 +- Control UI 在获取头像时会以 bearer 标头方式转发 gateway token,并使用已认证的 blob URL,因此图片仍能在仪表板中正常渲染。 -如果你禁用了 gateway 认证(不建议在共享主机上这样做),那么头像路由也会像 gateway 的其余部分一样变为无需认证。 +如果你关闭 gateway 认证(不建议在共享主机上这样做),头像路由也会像 gateway 其余部分一样变为未认证状态。 ## 构建 UI @@ -286,7 +278,7 @@ Gateway 网关会从 `dist/control-ui` 提供静态文件。使用以下命令 pnpm ui:build ``` -可选的绝对 base 路径(当你想使用固定资源 URL 时): +可选的绝对 base(当你想使用固定资源 URL 时): ```bash OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build @@ -300,9 +292,9 @@ pnpm ui:dev 然后将 UI 指向你的 Gateway WS URL(例如 `ws://127.0.0.1:18789`)。 -## 调试/测试:开发服务器 + 远程 Gateway +## 调试/测试:开发服务器 + 远程 Gateway 网关 -Control UI 是静态文件;WebSocket 目标可配置,并且可以与 HTTP 源不同。当你想在本地运行 Vite 开发服务器,而 Gateway 网关运行在其他地方时,这会很方便。 +Control UI 是静态文件;WebSocket 目标是可配置的,并且可以与 HTTP 源不同。当你希望在本地使用 Vite 开发服务器,但 Gateway 网关运行在别处时,这会非常方便。 1. 启动 UI 开发服务器:`pnpm ui:dev` 2. 打开如下 URL: @@ -319,19 +311,17 @@ http://localhost:5173/?gatewayUrl=wss://:18789#token=