diff --git a/docs/zh-CN/gateway/cli-backends.md b/docs/zh-CN/gateway/cli-backends.md index 23fa6e6b0..ec2f72ee2 100644 --- a/docs/zh-CN/gateway/cli-backends.md +++ b/docs/zh-CN/gateway/cli-backends.md @@ -1,48 +1,41 @@ --- read_when: - - 你想在 API 提供商失败时使用可靠的回退方案 + - 当 API 提供商失效时,你希望有一个可靠的回退方案 - 你正在运行 Codex CLI 或其他本地 AI CLI,并希望复用它们 - - 你想了解 CLI 后端工具访问的 MCP loopback 桥接机制 -summary: CLI 后端:带可选 MCP 工具桥接的本地 AI CLI 回退方案 + - 你想了解用于 CLI 后端工具访问的 MCP local loopback 桥接机制 +summary: CLI 后端:本地 AI CLI 回退,支持可选的 MCP 工具桥接 title: CLI 后端 x-i18n: - generated_at: "2026-04-23T20:48:13Z" + generated_at: "2026-04-23T21:49:31Z" model: gpt-5.4 provider: openai - source_hash: 86594b886c259df68591223e106c7507ab802321aaedebc9b243793c4f453388 + source_hash: d4f3f2f0a02539455de1a9f3982590e507e5ccd1e4cc354658118eadf522150a source_path: gateway/cli-backends.md workflow: 15 --- # CLI 后端(回退运行时) -当 API 提供商不可用、 -受到速率限制或暂时异常时,OpenClaw 可以将**本地 AI CLI** 作为**纯文本回退方案**运行。这个机制刻意保持保守: +当 API 提供商不可用、受到速率限制或暂时行为异常时,OpenClaw 可以运行**本地 AI CLI** 作为**纯文本回退**。这是一种有意保持保守的设计: -- **不会直接注入 OpenClaw 工具**,但带有 `bundleMcp: true` - 的后端可以通过 loopback MCP 桥接接收 Gateway 网关工具。 -- **支持 JSONL 流式传输**,适用于支持该能力的 CLI。 -- **支持会话**(因此后续轮次能保持连贯)。 -- **如果 CLI 接受图像路径**,则可以传递图像。 +- **不会直接注入 OpenClaw 工具**,但设置了 `bundleMcp: true` 的后端可以通过 loopback MCP 桥接接收 Gateway 网关工具。 +- 对支持该能力的 CLI 提供 **JSONL 流式传输**。 +- **支持会话**(因此后续轮次能够保持连贯)。 +- 如果 CLI 接受图片路径,**图片可以透传**。 -这被设计为一种**安全网**,而不是主路径。当你 -希望在不依赖外部 API 的情况下获得“始终可用”的文本回复时,可以使用它。 +这被设计为一个**安全兜底机制**,而不是主要路径。当你希望在不依赖外部 API 的情况下获得“始终可用”的文本响应时,可以使用它。 -如果你想要具有 ACP 会话控制、后台任务、 -线程 / 对话绑定以及持久化外部编码会话的完整 harness 运行时,请使用 -[ACP Agents](/zh-CN/tools/acp-agents)。CLI 后端不是 ACP。 +如果你想要一个具备 ACP 会话控制、后台任务、线程/会话绑定以及持久化外部编码会话的完整 harness 运行时,请改用 [ACP Agents](/zh-CN/tools/acp-agents)。CLI 后端不是 ACP。 ## 面向初学者的快速开始 -你可以**无需任何配置**使用 Codex CLI(内置 OpenAI 插件 -会注册一个默认后端): +你可以**无需任何配置**使用 Codex CLI(内置的 OpenAI 插件会注册一个默认后端): ```bash openclaw agent --message "hi" --model codex-cli/gpt-5.5 ``` -如果你的 Gateway 网关运行在 launchd / systemd 下,而 PATH 很精简,只需添加 -命令路径: +如果你的 Gateway 网关运行在 launchd/systemd 下,且 `PATH` 很精简,只需添加命令路径: ```json5 { @@ -58,15 +51,13 @@ openclaw agent --message "hi" --model codex-cli/gpt-5.5 } ``` -就这样。除了 CLI 本身之外,不需要额外的 key 或认证配置。 +就是这样。除了 CLI 自身所需的认证外,不需要密钥,也不需要额外的认证配置。 -如果你在 Gateway 网关主机上将某个内置 CLI 后端用作**主消息提供商**, -而你的配置又在模型引用或 -`agents.defaults.cliBackends` 下显式引用了该后端,那么 OpenClaw 现在会自动加载其所属的内置插件。 +如果你在 Gateway 网关主机上将内置的 CLI 后端用作**主要消息提供商**,当你的配置在模型引用或 `agents.defaults.cliBackends` 下显式引用该后端时,OpenClaw 现在会自动加载其所属的内置插件。 -## 将其作为回退使用 +## 将其用作回退 -将某个 CLI 后端添加到你的回退列表中,这样它只会在主模型失败时运行: +将 CLI 后端加入你的回退列表,这样它只会在主要模型失败时运行: ```json5 { @@ -87,9 +78,8 @@ openclaw agent --message "hi" --model codex-cli/gpt-5.5 说明: -- 如果你使用 `agents.defaults.models`(允许列表),你也必须把 CLI 后端模型包含进去。 -- 如果主提供商失败(认证、速率限制、超时),OpenClaw 将 - 接着尝试 CLI 后端。 +- 如果你使用 `agents.defaults.models`(允许列表),你也必须在其中包含 CLI 后端模型。 +- 如果主要提供商失败(认证、速率限制、超时),OpenClaw 会接着尝试 CLI 后端。 ## 配置概览 @@ -99,8 +89,8 @@ openclaw agent --message "hi" --model codex-cli/gpt-5.5 agents.defaults.cliBackends ``` -每个条目都以一个**提供商 id** 为键(例如 `codex-cli`、`my-cli`)。 -这个提供商 id 会成为你的模型引用左半部分: +每个条目都以**提供商 id** 为键(例如 `codex-cli`、`my-cli`)。 +该提供商 id 会成为模型引用左侧部分: ``` / @@ -130,7 +120,7 @@ agents.defaults.cliBackends sessionMode: "existing", sessionIdFields: ["session_id", "conversation_id"], systemPromptArg: "--system", - // Codex 风格 CLI 可以改为指向提示词文件: + // Codex 风格的 CLI 也可以改为指向一个提示文件: // systemPromptFileConfigArg: "-c", // systemPromptFileConfigKey: "model_instructions_file", systemPromptWhen: "first", @@ -146,33 +136,25 @@ agents.defaults.cliBackends ## 工作原理 -1. **根据提供商前缀选择后端**(`codex-cli/...`)。 -2. **使用相同的 OpenClaw 提示词 + 工作区上下文构建系统提示词**。 -3. **使用会话 id 执行 CLI**(如果支持),以保持历史一致。 - 内置的 `claude-cli` 后端会为每个 - OpenClaw 会话保持一个 Claude stdio 进程存活,并通过 stream-json stdin 发送后续轮次。 +1. 根据提供商前缀(`codex-cli/...`)**选择后端**。 +2. 使用相同的 OpenClaw 提示词和工作区上下文**构建系统提示词**。 +3. 使用会话 id(如果支持)**执行 CLI**,以保持历史一致。 + 内置的 `claude-cli` 后端会为每个 OpenClaw 会话保持一个 Claude stdio 进程存活, + 并通过 stream-json stdin 发送后续轮次。 4. **解析输出**(JSON 或纯文本),并返回最终文本。 -5. **按后端持久化会话 id**,这样后续轮次会复用相同的 CLI 会话。 +5. 按后端**持久化会话 id**,以便后续轮次复用同一个 CLI 会话。 -内置 Anthropic `claude-cli` 后端现已重新受支持。Anthropic 工作人员 -告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此 OpenClaw 将 -`claude -p` 用法视为此集成的许可用法,除非 Anthropic 发布 -新的政策。 +内置的 Anthropic `claude-cli` 后端现已再次受支持。Anthropic 员工告诉我们,允许使用 OpenClaw 风格的 Claude CLI,因此除非 Anthropic 发布新的策略,否则 OpenClaw 会将这种集成中的 `claude -p` 用法视为被认可的方式。 -内置 OpenAI `codex-cli` 后端会通过 -Codex 的 `model_instructions_file` 配置覆盖项(`-c -model_instructions_file="..."`)传递 OpenClaw 的系统提示词。Codex 不提供类似 Claude 风格的 -`--append-system-prompt` 标志,因此 OpenClaw 会为每个新的 Codex CLI 会话 -将组装后的提示词写入一个临时文件。 +内置的 OpenAI `codex-cli` 后端通过 Codex 的 `model_instructions_file` 配置覆盖项(`-c +model_instructions_file="..."`)传递 OpenClaw 的系统提示词。Codex 不提供类似 Claude 的 +`--append-system-prompt` 标志,因此 OpenClaw 会为每个新的 Codex CLI 会话将组装好的提示词写入一个临时文件。 -内置 Anthropic `claude-cli` 后端会通过 -两种方式接收 OpenClaw 的 Skills 快照:一种是附加系统提示词中的紧凑 OpenClaw Skills 目录,另一种是 -通过 `--plugin-dir` 传入的临时 Claude Code 插件。该插件仅包含对该智能体 / 会话适用的 Skills, -因此 Claude Code 原生 Skills 解析器看到的就是与 OpenClaw 在提示词中会公布的同一套经过筛选的内容。Skill 环境变量 / API key 覆盖仍由 OpenClaw 应用于该次运行的子进程环境。 +内置的 Anthropic `claude-cli` 后端会通过两种方式接收 OpenClaw 的 Skills 快照:一种是附加系统提示词中的精简版 OpenClaw Skills 目录,另一种是通过 `--plugin-dir` 传入的临时 Claude Code 插件。该插件仅包含对该智能体/会话可用的 Skills,因此 Claude Code 的原生 skill 解析器看到的过滤后集合,与 OpenClaw 原本会在提示词中声明的集合相同。针对 Skill 的环境变量/API 密钥覆盖仍然会由 OpenClaw 应用到本次运行的子进程环境中。 -在 OpenClaw 可以使用内置 `claude-cli` 后端之前,Claude Code 本身必须已经在同一台主机上登录: +在 OpenClaw 可以使用内置的 `claude-cli` 后端之前,Claude Code 本身必须已经在同一台主机上登录: ```bash claude auth login @@ -180,75 +162,56 @@ claude auth status --text openclaw models auth login --provider anthropic --method cli --set-default ``` -仅当 `claude` -二进制文件尚未存在于 `PATH` 中时,才使用 `agents.defaults.cliBackends.claude-cli.command`。 +只有当 `claude` 二进制文件不在 `PATH` 中时,才需要使用 `agents.defaults.cliBackends.claude-cli.command`。 ## 会话 - 如果 CLI 支持会话,请设置 `sessionArg`(例如 `--session-id`)或 - `sessionArgs`(占位符 `{sessionId}`),当需要将 ID 插入 - 到多个标志中时使用。 -- 如果 CLI 使用带有不同标志的**resume 子命令**,请设置 - `resumeArgs`(恢复时替代 `args`),并可选设置 - `resumeOutput`(用于非 JSON 恢复)。 + `sessionArgs`(占位符 `{sessionId}`),用于需要将 id 插入多个标志的情况。 +- 如果 CLI 使用带有不同标志的**恢复子命令**,请设置 + `resumeArgs`(恢复时替换 `args`),并可选设置 `resumeOutput` + (用于非 JSON 的恢复)。 - `sessionMode`: - - `always`:总是发送会话 id(如果未存储,则生成新的 UUID)。 - - `existing`:仅在之前已存储会话 id 时发送。 - - `none`:永不发送会话 id。 + - `always`:始终发送会话 id(如果未存储则生成新的 UUID)。 + - `existing`:仅在之前已存储时发送会话 id。 + - `none`:从不发送会话 id。 - `claude-cli` 默认使用 `liveSession: "claude-stdio"`、`output: "jsonl"`、 - 和 `input: "stdin"`,因此后续轮次会在 Claude 进程仍处于活动状态时复用该活动 Claude 进程。 - 现在 warm stdio 是默认行为,包括那些省略传输字段的自定义配置 - 也是如此。如果 Gateway 网关重启,或者空闲进程 - 退出,OpenClaw 会从已存储的 Claude 会话 id 恢复。已存储的会话 - id 会先与现有可读的项目转录进行校验,再执行 - 恢复,因此虚假的绑定会以 `reason=transcript-missing` - 被清除,而不是在 `--resume` 下静默启动新的 Claude CLI 会话。 -- 已存储的 CLI 会话属于提供商拥有的连续性。隐式的每日会话 - 重置不会中断它们;`/reset` 和显式 `session.reset` 策略 - 才会。 + 和 `input: "stdin"`,这样在 Claude 进程仍处于活动状态时,后续轮次就能复用该实时 Claude 进程。现在默认就是预热的 stdio,包括那些省略传输字段的自定义配置。如果 Gateway 网关重启,或者空闲进程退出,OpenClaw 会从已存储的 Claude 会话 id 恢复。已存储的会话 id 会先针对现有且可读的项目转录进行校验,再执行恢复,因此虚假的绑定会以 `reason=transcript-missing` 被清除,而不是在 `--resume` 下悄悄启动一个全新的 Claude CLI 会话。 +- 已存储的 CLI 会话属于提供商自身的连续性状态。隐式的每日会话重置不会切断它们;`/reset` 和显式的 `session.reset` 策略仍然会切断。 序列化说明: -- `serialize: true` 会保持同一通道中的运行按顺序执行。 -- 大多数 CLI 都会在一个提供商通道上串行化。 -- 当所选认证身份发生变化时,OpenClaw 会放弃复用已存储的 CLI 会话, - 包括 auth profile id 变化、静态 API key 变化、静态 token 变化,或 - 当 CLI 暴露该信息时 OAuth 账户身份变化。 - OAuth access token 和 refresh token 的轮换不会中断已存储的 CLI 会话。 - 如果某个 CLI 不暴露稳定的 OAuth 账户 id,OpenClaw 会让该 CLI 自行强制执行恢复权限。 +- `serialize: true` 会保持同一执行通道中的运行顺序。 +- 大多数 CLI 会在一个提供商通道上串行执行。 +- 当所选认证身份发生变化时,OpenClaw 会放弃复用已存储的 CLI 会话,包括认证配置文件 id、静态 API 密钥、静态令牌,或 CLI 暴露该信息时的 OAuth 账户身份发生变化。OAuth 访问令牌和刷新令牌轮换不会切断已存储的 CLI 会话。如果某个 CLI 没有暴露稳定的 OAuth 账户 id,OpenClaw 会让该 CLI 自行强制执行恢复权限。 -## 图像(透传) +## 图片(透传) -如果你的 CLI 接受图像路径,请设置 `imageArg`: +如果你的 CLI 接受图片路径,请设置 `imageArg`: ```json5 imageArg: "--image", imageMode: "repeat" ``` -OpenClaw 会将 base64 图像写入临时文件。如果设置了 `imageArg`, -这些路径就会作为 CLI 参数传入。如果缺少 `imageArg`,OpenClaw 会将 -文件路径追加到提示词中(路径注入),这足以满足那些会从普通路径自动 -加载本地文件的 CLI。 +OpenClaw 会将 base64 图片写入临时文件。如果设置了 `imageArg`,这些路径会作为 CLI 参数传入。如果缺少 `imageArg`,OpenClaw 会将文件路径附加到提示词中(路径注入),这对于那些能从普通路径自动加载本地文件的 CLI 已经足够。 ## 输入 / 输出 -- `output: "json"`(默认)会尝试解析 JSON,并提取文本 + 会话 id。 -- 对于 Gemini CLI JSON 输出,当 `usage` 缺失或为空时,OpenClaw 会从 `response` 读取回复文本, - 并从 `stats` 读取用量。 -- `output: "jsonl"` 会解析 JSONL 流(例如 Codex CLI `--json`),并提取最终智能体消息以及会话 - 标识符(如果存在)。 +- `output: "json"`(默认)会尝试解析 JSON 并提取文本和会话 id。 +- 对于 Gemini CLI 的 JSON 输出,当 `usage` 缺失或为空时,OpenClaw 会从 `response` 读取回复文本,并从 `stats` 读取用量。 +- `output: "jsonl"` 会解析 JSONL 流(例如 Codex CLI `--json`),并提取最终的智能体消息以及存在时的会话标识符。 - `output: "text"` 将 stdout 视为最终响应。 输入模式: - `input: "arg"`(默认)将提示词作为最后一个 CLI 参数传递。 - `input: "stdin"` 通过 stdin 发送提示词。 -- 如果提示词很长并设置了 `maxPromptArgChars`,则会改用 stdin。 +- 如果提示词很长并且设置了 `maxPromptArgChars`,则会使用 stdin。 -## 默认值(由插件持有) +## 默认值(插件拥有) -内置 OpenAI 插件还会为 `codex-cli` 注册一个默认值: +内置的 OpenAI 插件也会为 `codex-cli` 注册一个默认值: - `command: "codex"` - `args: ["exec","--json","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]` @@ -259,7 +222,7 @@ OpenClaw 会将 base64 图像写入临时文件。如果设置了 `imageArg`, - `imageArg: "--image"` - `sessionMode: "existing"` -内置 Google 插件也会为 `google-gemini-cli` 注册一个默认值: +内置的 Google 插件也会为 `google-gemini-cli` 注册一个默认值: - `command: "gemini"` - `args: ["--output-format", "json", "--prompt", "{prompt}"]` @@ -270,31 +233,31 @@ OpenClaw 会将 base64 图像写入临时文件。如果设置了 `imageArg`, - `sessionMode: "existing"` - `sessionIdFields: ["session_id", "sessionId"]` -前提条件:本地 Gemini CLI 必须已安装,并且可以通过 -`PATH` 中的 `gemini` 访问(`brew install gemini-cli` 或 +前提条件:本地 Gemini CLI 必须已安装,并且可以通过 `PATH` 中的 +`gemini` 调用(`brew install gemini-cli` 或 `npm install -g @google/gemini-cli`)。 Gemini CLI JSON 说明: -- 回复文本从 JSON `response` 字段读取。 -- 当 `usage` 不存在或为空时,用量回退到 `stats`。 -- `stats.cached` 会被标准化为 OpenClaw 的 `cacheRead`。 -- 如果 `stats.input` 缺失,OpenClaw 会根据 +- 回复文本从 JSON 的 `response` 字段读取。 +- 当 `usage` 不存在或为空时,用量会回退到 `stats`。 +- `stats.cached` 会被标准化为 OpenClaw `cacheRead`。 +- 如果缺少 `stats.input`,OpenClaw 会根据 `stats.input_tokens - stats.cached` 推导输入 token 数。 -仅在需要时覆盖(常见情况:绝对 `command` 路径)。 +仅在需要时覆盖(常见情况:使用绝对 `command` 路径)。 -## 由插件持有的默认值 +## 插件拥有的默认值 CLI 后端默认值现在属于插件表面的一部分: - 插件通过 `api.registerCliBackend(...)` 注册它们。 - 后端 `id` 会成为模型引用中的提供商前缀。 -- 用户在 `agents.defaults.cliBackends.` 中的配置仍会覆盖插件默认值。 -- 后端特定的配置清理由插件通过可选 - `normalizeConfig` hook 持有。 +- 位于 `agents.defaults.cliBackends.` 下的用户配置仍会覆盖插件默认值。 +- 特定后端的配置清理仍通过可选的 + `normalizeConfig` hook 由插件负责。 -需要进行微小提示词 / 消息兼容性调整的插件,可以声明双向文本转换,而无需替换提供商或 CLI 后端: +如果插件需要细微的提示词/消息兼容性 shim,可以声明双向文本转换,而无需替换提供商或 CLI 后端: ```typescript api.registerTextTransforms({ @@ -312,50 +275,50 @@ api.registerTextTransforms({ ``` `input` 会重写传递给 CLI 的系统提示词和用户提示词。`output` -会在 OpenClaw 处理其自身控制标记和渠道投递之前,重写流式助手增量和解析后的最终文本。 +会在 OpenClaw 处理其自身控制标记和渠道投递之前,重写流式传输的 assistant 增量内容以及解析后的最终文本。 -对于输出 Claude Code stream-json 兼容 JSONL 的 CLI, -请在该后端配置中设置 +对于输出与 Claude Code stream-json 兼容的 JSONL 的 CLI,请在该后端配置中设置 `jsonlDialect: "claude-stream-json"`。 ## Bundle MCP 覆盖层 -CLI 后端**不会**直接接收 OpenClaw 工具调用,但某个后端可以 -通过 `bundleMcp: true` 选择启用自动生成的 MCP 配置覆盖层。 +CLI 后端**不会**直接接收 OpenClaw 工具调用,但后端可以通过设置 +`bundleMcp: true` 选择加入一个生成的 MCP 配置覆盖层。 -当前内置行为: +当前的内置行为: -- `claude-cli`:自动生成严格 MCP 配置文件 -- `codex-cli`:`mcp_servers` 的内联配置覆盖 -- `google-gemini-cli`:自动生成 Gemini 系统设置文件 +- `claude-cli`:生成严格的 MCP 配置文件 +- `codex-cli`:为 `mcp_servers` 生成内联配置覆盖;生成的 + OpenClaw loopback 服务器会标记为 Codex 的每服务器工具批准模式, + 这样 MCP 调用就不会因为本地批准提示而卡住 +- `google-gemini-cli`:生成 Gemini system settings 文件 -启用 bundle MCP 时,OpenClaw 会: +启用 bundle MCP 时,OpenClaw: -- 启动一个 loopback HTTP MCP 服务器,将 Gateway 网关工具暴露给 CLI 进程 -- 使用按会话生成的令牌(`OPENCLAW_MCP_TOKEN`)对桥接进行身份验证 -- 将工具访问范围限制在当前会话、账户和渠道上下文中 +- 启动一个 loopback HTTP MCP 服务器,向 CLI 进程暴露 Gateway 网关工具 +- 使用每会话令牌(`OPENCLAW_MCP_TOKEN`)对桥接进行认证 +- 将工具访问范围限制在当前会话、账户和渠道上下文内 - 为当前工作区加载已启用的 bundle-MCP 服务器 -- 将它们与任何现有的后端 MCP 配置 / 设置结构合并 -- 使用所属扩展定义的后端集成模式重写启动配置 +- 将它们与任何现有的后端 MCP 配置/设置结构合并 +- 使用所属扩展中由后端拥有的集成模式重写启动配置 -如果没有启用任何 MCP 服务器,只要某个 -后端选择启用 bundle MCP,OpenClaw 仍会注入严格配置,以便后台运行保持隔离。 +如果没有启用任何 MCP 服务器,当后端选择加入 bundle MCP 时,OpenClaw 仍会注入严格配置,以便后台运行保持隔离。 ## 限制 -- **没有直接的 OpenClaw 工具调用。** OpenClaw 不会将工具调用直接注入 - 到 CLI 后端协议中。后端只有在选择启用 - `bundleMcp: true` 时,才会看到 Gateway 网关工具。 -- **流式传输取决于后端。** 有些后端会流式输出 JSONL;其他后端则会缓冲 +- **没有直接的 OpenClaw 工具调用。** OpenClaw 不会将工具调用注入到 + CLI 后端协议中。只有当后端选择加入 + `bundleMcp: true` 时,后端才会看到 Gateway 网关工具。 +- **流式传输是后端特定的。** 一些后端流式传输 JSONL;另一些则会缓冲 直到退出。 -- **结构化输出**取决于 CLI 的 JSON 格式。 -- **Codex CLI 会话**通过文本输出恢复(没有 JSONL),因此其结构化程度 - 不如初始的 `--json` 运行。不过 OpenClaw 会话本身仍可正常工作。 +- **结构化输出** 取决于 CLI 的 JSON 格式。 +- **Codex CLI 会话** 通过文本输出恢复(没有 JSONL),其结构化程度 + 低于初始的 `--json` 运行。不过 OpenClaw 会话本身仍可正常工作。 ## 故障排除 -- **找不到 CLI:** 请将 `command` 设置为完整路径。 -- **模型名称错误:** 使用 `modelAliases` 将 `provider/model` 映射到 CLI 模型。 -- **没有会话连续性:** 请确保已设置 `sessionArg`,且 `sessionMode` 不是 - `none`(Codex CLI 当前无法通过 JSON 输出恢复)。 -- **图像被忽略:** 请设置 `imageArg`(并确认 CLI 支持文件路径)。 +- **找不到 CLI**:将 `command` 设置为完整路径。 +- **模型名称错误**:使用 `modelAliases` 将 `provider/model` 映射到 CLI 模型。 +- **没有会话连续性**:确保已设置 `sessionArg`,且 `sessionMode` 不为 + `none`(Codex CLI 当前无法使用 JSON 输出恢复)。 +- **图片被忽略**:设置 `imageArg`(并确认 CLI 支持文件路径)。 diff --git a/docs/zh-CN/help/testing.md b/docs/zh-CN/help/testing.md index 7dfcef0c8..8fd2f8739 100644 --- a/docs/zh-CN/help/testing.md +++ b/docs/zh-CN/help/testing.md @@ -1,157 +1,128 @@ --- read_when: - 在本地或 CI 中运行测试 - - 为模型/提供商缺陷添加回归测试 + - 为模型 / 提供商缺陷添加回归测试 - 调试 Gateway 网关 + 智能体行为 -summary: 测试工具包:单元/e2e/live 测试套件、Docker 运行器,以及各测试覆盖内容 +summary: 测试工具包:单元 / e2e / live 测试套件、Docker 运行器,以及每类测试覆盖的内容 title: 测试 x-i18n: - generated_at: "2026-04-23T20:51:17Z" + generated_at: "2026-04-23T21:49:28Z" model: gpt-5.4 provider: openai - source_hash: 0e0486e188407275915672b0f3955fcd52652cad6b11dbe3195644c539f9179e + source_hash: 3cbd2be379692062162981a8709218dc62f37bb1517d03d561b6da1f7af1f923 source_path: help/testing.md workflow: 15 --- -OpenClaw 有三套 Vitest 测试套件(单元/集成、e2e、live)以及一小组 -Docker 运行器。本文是一份“我们如何测试”的指南: +OpenClaw 有三个 Vitest 测试套件(unit/integration、e2e、live)以及一小组 Docker 运行器。本文档是一份“我们的测试方式”指南: -- 每个测试套件覆盖什么(以及它有意**不**覆盖什么)。 -- 常见工作流应运行哪些命令(本地、push 前、调试)。 -- live 测试如何发现凭证,以及如何选择模型/提供商。 -- 如何为真实世界的模型/提供商问题添加回归测试。 +- 每个测试套件覆盖的内容(以及它刻意 _不_ 覆盖的内容)。 +- 常见工作流应运行哪些命令(本地、推送前、调试)。 +- live 测试如何发现凭证并选择模型 / 提供商。 +- 如何为真实世界中的模型 / 提供商问题添加回归测试。 ## 快速开始 -大多数日常情况: +大多数时候: -- 完整门禁(通常要求在 push 前完成):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` -- 在资源充足机器上更快地运行本地全套测试:`pnpm test:max` -- 直接进入 Vitest watch 循环:`pnpm test:watch` -- 直接按文件定位现在也支持 extension/channel 路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` -- 当你在迭代单个失败用例时,优先运行有针对性的测试。 -- Docker 支持的 QA 站点:`pnpm qa:lab:up` +- 完整门禁(预期应在推送前运行):`pnpm build && pnpm check && pnpm check:test-types && pnpm test` +- 在配置充足的机器上更快地运行本地完整测试套件:`pnpm test:max` +- 直接使用 Vitest 观察循环:`pnpm test:watch` +- 直接按文件定位现在也支持 extension / channel 路径:`pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` +- 当你在迭代单个失败用例时,优先先运行有针对性的测试。 +- 基于 Docker 的 QA 站点:`pnpm qa:lab:up` - 基于 Linux VM 的 QA 通道:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline` -当你修改了测试,或希望获得更高信心时: +当你修改测试或希望获得更多信心时: - 覆盖率门禁:`pnpm test:coverage` -- E2E 套件:`pnpm test:e2e` +- E2E 测试套件:`pnpm test:e2e` -当你要调试真实提供商/模型时(需要真实凭证): +当调试真实提供商 / 模型时(需要真实凭证): -- Live 套件(模型 + Gateway 网关工具/图像探测):`pnpm test:live` -- 安静地只跑一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` +- live 测试套件(模型 + Gateway 网关工具 / 图像探测):`pnpm test:live` +- 静默地只运行一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts` - Docker live 模型扫描:`pnpm test:docker:live-models` - - 现在每个选定模型都会运行一个文本轮次 + 一个小型文件读取风格探测。 - 元数据声明支持 `image` 输入的模型还会运行一个很小的图像轮次。 - 在隔离提供商故障时,可使用 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 - `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用这些额外探测。 - - CI 覆盖:每日运行的 `OpenClaw Scheduled Live And E2E Checks` 和手动触发的 - `OpenClaw Release Checks` 都会调用可复用的 live/E2E 工作流,并设置 - `include_live_suites: true`,其中包含按提供商分片的独立 Docker live 模型 - matrix 作业。 - - 若要做有针对性的 CI 重跑,可调度 `OpenClaw Live And E2E Checks (Reusable)`, - 设置 `include_live_suites: true` 和 `live_models_only: true`。 - - 为新的高信号提供商秘密添加支持时,请同时更新 `scripts/ci-hydrate-live-auth.sh` 以及 `.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 和其定时/发布调用方。 -- Moonshot/Kimi 成本 smoke:设置 `MOONSHOT_API_KEY` 后,先运行 - `openclaw models list --provider moonshot --json`,然后针对 `moonshot/kimi-k2.6` - 运行一个隔离的 - `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json` - 。验证 JSON 报告的是 Moonshot/K2.6,并且助手转录中存储了规范化后的 `usage.cost`。 + - 现在每个被选中的模型都会运行一次文本轮次外加一个小型的文件读取式探测。元数据声明支持 `image` 输入的模型还会运行一个微型图像轮次。在隔离提供商故障时,可通过 `OPENCLAW_LIVE_MODEL_FILE_PROBE=0` 或 `OPENCLAW_LIVE_MODEL_IMAGE_PROBE=0` 禁用这些额外探测。 + - CI 覆盖范围:每日的 `OpenClaw Scheduled Live And E2E Checks` 以及手动触发的 `OpenClaw Release Checks` 都会调用可复用的 live / E2E 工作流,并传入 `include_live_suites: true`,其中包含按提供商分片的独立 Docker live 模型矩阵作业。 + - 若要进行聚焦式 CI 重跑,可触发 `OpenClaw Live And E2E Checks (Reusable)`,并设置 `include_live_suites: true` 和 `live_models_only: true`。 + - 把新的高信号提供商密钥添加到 `scripts/ci-hydrate-live-auth.sh`、`.github/workflows/openclaw-live-and-e2e-checks-reusable.yml` 以及其对应的定时 / 发布调用工作流中。 +- Moonshot / Kimi 成本冒烟测试:设置 `MOONSHOT_API_KEY` 后,运行 `openclaw models list --provider moonshot --json`,然后针对 `moonshot/kimi-k2.6` 运行独立命令 `openclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --json`。验证 JSON 中报告的是 Moonshot / K2.6,且 assistant transcript 存储了规范化后的 `usage.cost`。 -提示:当你只需要一个失败用例时,优先通过下面描述的允许列表环境变量来收窄 live 测试范围。 +提示:如果你只需要一个失败用例,优先使用下文描述的 allowlist 环境变量来缩小 live 测试范围。 ## QA 专用运行器 -当你需要 QA-lab 级别的真实性时,这些命令与主测试套件并列存在: +当你需要 QA-lab 的真实环境时,这些命令与主测试套件并列使用: -CI 会在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行, -也可通过手动调度以 mock 提供商运行。`QA-Lab - All Lanes` 会在 `main` 分支上每晚运行, -也可手动调度,作为并行作业运行 mock parity gate、live Matrix 通道以及由 Convex 管理的 live Telegram 通道。`OpenClaw Release Checks` -会在批准发布前运行相同通道。 +CI 会在专用工作流中运行 QA Lab。`Parity gate` 会在匹配的 PR 上运行,也可通过手动触发使用 mock 提供商运行。`QA-Lab - All Lanes` 会在 `main` 上每晚运行,也可手动触发;它会并行运行 mock parity gate、live Matrix 通道以及由 Convex 管理的 live Telegram 通道作业。`OpenClaw Release Checks` 会在发布审批前运行相同的通道。 - `pnpm openclaw qa suite` - 直接在主机上运行基于仓库的 QA 场景。 - - 默认会在隔离的 Gateway 网关 worker 中并行运行多个所选场景。 - `qa-channel` 默认并发数为 4(受所选场景数量限制)。 - 使用 `--concurrency ` 调整 worker - 数量,或使用 `--concurrency 1` 回到旧的串行通道。 - - 任何场景失败时都会以非零状态退出。若你只想保留产物而不希望退出失败,请使用 `--allow-failures`。 - - 支持 `live-frontier`、`mock-openai` 和 `aimock` 提供商模式。 - `aimock` 会启动一个基于本地 AIMock 的提供商服务器,用于实验性的 - fixture 和协议 mock 覆盖,而不会替代具备场景感知的 `mock-openai` 通道。 + - 默认会使用隔离的 Gateway 网关 worker 并行运行多个选定场景。`qa-channel` 默认并发数为 4(上限受所选场景数量约束)。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 回退到较早的串行通道。 + - 当任一场景失败时,以非零状态退出。若你希望保留制品而不返回失败退出码,请使用 `--allow-failures`。 + - 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个本地由 AIMock 支持的提供商服务器,用于实验性的 fixture 与协议 mock 覆盖,但不会替代具备场景感知能力的 `mock-openai` 通道。 - `pnpm openclaw qa suite --runner multipass` - - 在一次性的 Multipass Linux VM 中运行相同的 QA 套件。 + - 在一次性的 Multipass Linux VM 内运行同一套 QA 测试。 - 与主机上的 `qa suite` 保持相同的场景选择行为。 - - 复用与 `qa suite` 相同的提供商/模型选择标志。 - - live 运行会向来宾转发受支持且实际可用的 QA 认证输入: - 基于环境变量的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`。 - - 输出目录必须保持在仓库根目录下,这样来宾才能通过挂载的工作区写回。 - - 会将常规 QA 报告 + 摘要以及 Multipass 日志写入 - `.artifacts/qa-e2e/...`。 + - 复用与 `qa suite` 相同的提供商 / 模型选择标志。 + - live 运行会转发对来宾环境而言可行的受支持 QA 凭证输入:基于环境变量的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`。 + - 输出目录必须保持在仓库根目录下,以便来宾可通过挂载的工作区回写内容。 + - 会将常规 QA 报告 + 摘要以及 Multipass 日志写入 `.artifacts/qa-e2e/...`。 - `pnpm qa:lab:up` - - 启动基于 Docker 的 QA 站点,用于运维风格的 QA 工作。 + - 启动基于 Docker 的 QA 站点,供偏操作员风格的 QA 工作使用。 - `pnpm test:docker:npm-onboard-channel-agent` - - 从当前检出构建 npm tarball,在 Docker 中全局安装, - 运行非交互式 OpenAI API 密钥新手引导,默认配置 Telegram, - 验证启用插件时会按需安装运行时依赖,运行 doctor, - 并针对一个 mock 的 OpenAI 端点执行一次本地智能体轮次。 - - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可在 Discord 上运行同样的打包安装通道。 + - 从当前 checkout 构建 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API 密钥新手引导,默认配置 Telegram,验证启用插件时会按需安装运行时依赖,运行 doctor,并针对一个 mock 的 OpenAI 端点运行一次本地智能体轮次。 + - 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可用 Discord 运行同一条打包安装通道。 - `pnpm test:docker:bundled-channel-deps` - - 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关, - 然后通过配置编辑启用内置渠道/插件。 - - 验证 setup discovery 不会提前安装尚未配置插件的运行时依赖,首次配置后的 Gateway 网关或 doctor 运行会按需安装每个内置插件的运行时依赖,而第二次重启不会重新安装已经激活过的依赖。 - - 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag ` 之前先启用 Telegram,并验证候选版本的更新后 doctor 能修复内置渠道运行时依赖,而无需 harness 侧的 postinstall 修复。 + - 在 Docker 中打包并安装当前的 OpenClaw 构建,使用已配置的 OpenAI 启动 Gateway 网关,然后通过编辑配置启用内置 channel / plugins。 + - 验证设置发现流程会让未配置插件的运行时依赖保持未安装状态;首次配置好的 Gateway 网关或 doctor 运行会按需安装每个内置插件的运行时依赖;第二次重启不会重新安装已激活的依赖。 + - 还会安装一个已知的较旧 npm 基线,在运行 `openclaw update --tag ` 之前先启用 Telegram,并验证候选版本在更新后的 doctor 中能够修复内置 channel 运行时依赖,而无需测试框架侧的 postinstall 修复。 - `pnpm openclaw qa aimock` - - 仅启动本地 AIMock 提供商服务器,用于直接协议 smoke 测试。 + - 仅启动本地 AIMock 提供商服务器,用于直接的协议冒烟测试。 - `pnpm openclaw qa matrix` - 针对一次性的、基于 Docker 的 Tuwunel homeserver 运行 Matrix live QA 通道。 - - 该 QA 主机目前仅供仓库/开发使用。打包安装的 OpenClaw 不会附带 - `qa-lab`,因此不会暴露 `openclaw qa`。 - - 仓库检出会直接加载内置运行器;无需单独安装插件。 - - 会创建三个临时 Matrix 用户(`driver`、`sut`、`observer`)以及一个私有房间,然后启动一个 QA Gateway 网关子进程,并将真实 Matrix 插件作为 SUT 传输层。 - - 默认使用固定稳定版 Tuwunel 镜像 `ghcr.io/matrix-construct/tuwunel:v1.5.1`。若需测试其他镜像,可用 `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` 覆盖。 - - Matrix 不暴露共享凭证来源标志,因为该通道会在本地创建一次性用户。 - - 会将 Matrix QA 报告、摘要、observed-events 产物以及合并后的 stdout/stderr 输出日志写入 `.artifacts/qa-e2e/...`。 + - 该 QA 主机目前仅供仓库 / 开发使用。打包后的 OpenClaw 安装不包含 `qa-lab`,因此不会暴露 `openclaw qa`。 + - 仓库 checkout 会直接加载内置运行器;无需单独安装插件。 + - 预配三个临时 Matrix 用户(`driver`、`sut`、`observer`)以及一个私有房间,然后启动一个将真实 Matrix 插件作为 SUT 传输层的 QA gateway 子进程。 + - 默认使用固定的稳定版 Tuwunel 镜像 `ghcr.io/matrix-construct/tuwunel:v1.5.1`。若需测试其他镜像,可使用 `OPENCLAW_QA_MATRIX_TUWUNEL_IMAGE` 覆盖。 + - Matrix 不提供共享的凭证来源标志,因为该通道会在本地预配一次性用户。 + - 会将 Matrix QA 报告、摘要、observed-events 制品以及合并后的 stdout / stderr 输出日志写入 `.artifacts/qa-e2e/...`。 - `pnpm openclaw qa telegram` - - 针对真实私有群组,使用来自环境变量的 driver 和 SUT bot 令牌运行 Telegram live QA 通道。 - - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 ID 必须是 Telegram 数字聊天 ID。 - - 支持 `--credential-source convex`,用于共享池化凭证。默认请使用 env 模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用池化租约。 - - 任何场景失败时都会以非零状态退出。若你只想保留产物而不希望退出失败,请使用 `--allow-failures`。 - - 需要两个不同的机器人位于同一个私有群组中,并且 SUT 机器人需暴露 Telegram 用户名。 - - 为了稳定地观察 bot-to-bot 通信,请在 `@BotFather` 中为两个机器人启用 Bot-to-Bot Communication Mode,并确保 driver 机器人可以观察群组内机器人流量。 - - 会将 Telegram QA 报告、摘要以及 observed-messages 产物写入 `.artifacts/qa-e2e/...`。回复类场景还会包含从 driver 发送请求到观察到 SUT 回复的 RTT。 + - 使用环境变量中的 driver 和 SUT bot token,针对真实私有群组运行 Telegram live QA 通道。 + - 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。群组 id 必须是 Telegram chat 的数字 id。 + - 支持通过 `--credential-source convex` 使用共享的池化凭证。默认使用 env 模式,或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用池化租约。 + - 当任一场景失败时,以非零状态退出。若你希望保留制品而不返回失败退出码,请使用 `--allow-failures`。 + - 需要同一私有群组中的两个不同 bot,且 SUT bot 需公开 Telegram 用户名。 + - 为获得稳定的 bot-to-bot 观测,请在 `@BotFather` 中为两个 bot 都启用 Bot-to-Bot Communication Mode,并确保 driver bot 可以观察群组中的 bot 流量。 + - 会将 Telegram QA 报告、摘要和 observed-messages 制品写入 `.artifacts/qa-e2e/...`。回复场景包含从 driver 发送请求到观测到 SUT 回复的 RTT。 -Live 传输通道共享一个标准契约,以防新传输层发生漂移: +live 传输通道共享同一份标准契约,以避免新传输协议出现漂移: -`qa-channel` 仍然是广义的合成 QA 套件,不属于 live -传输覆盖矩阵的一部分。 +`qa-channel` 仍然是覆盖面广的合成 QA 测试套件,不属于 live 传输覆盖矩阵的一部分。 -| 通道 | Canary | 提及门控 | 允许列表拦截 | 顶层回复 | 重启恢复 | 线程后续 | 线程隔离 | 表情观察 | 帮助命令 | -| -------- | ------ | -------------- | --------------- | --------------- | -------------- | ---------------- | ---------------- | -------------------- | ------------ | +| 通道 | Canary | 提及门控 | Allowlist 阻止 | 顶层回复 | 重启恢复 | 线程后续跟进 | 线程隔离 | 反应观测 | 帮助命令 | +| ---- | ------ | -------- | -------------- | -------- | -------- | ------------ | -------- | -------- | -------- | | Matrix | x | x | x | x | x | x | x | x | | | Telegram | x | | | | | | | | x | ### 通过 Convex 共享 Telegram 凭证(v1) -当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时, -QA lab 会从 Convex 支持的池中获取独占租约,在通道运行期间持续发送租约 heartbeat,并在关闭时释放租约。 +当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从基于 Convex 的池中获取一个独占租约,在通道运行期间对该租约发送心跳,并在关闭时释放该租约。 -参考 Convex 项目脚手架: +参考用的 Convex 项目脚手架: - `qa/convex-credential-broker/` -必需环境变量: +必需的环境变量: - `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`) -- 针对所选角色的一个 secret: - - `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER` 用于 `maintainer` - - `OPENCLAW_QA_CONVEX_SECRET_CI` 用于 `ci` +- 针对所选角色的一个密钥: + - `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`,用于 `maintainer` + - `OPENCLAW_QA_CONVEX_SECRET_CI`,用于 `ci` - 凭证角色选择: - CLI:`--credential-role maintainer|ci` - - 环境变量默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认 `ci`,否则默认 `maintainer`) + - 环境默认值:`OPENCLAW_QA_CREDENTIAL_ROLE`(在 CI 中默认为 `ci`,否则默认为 `maintainer`) 可选环境变量: @@ -160,13 +131,12 @@ QA lab 会从 Convex 支持的池中获取独占租约,在通道运行期间 - `OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS`(默认 `90000`) - `OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS`(默认 `15000`) - `OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX`(默认 `/qa-credentials/v1`) -- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选追踪 ID) -- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许仅用于本地开发的 loopback `http://` Convex URL。 +- `OPENCLAW_QA_CREDENTIAL_OWNER_ID`(可选的跟踪 id) +- `OPENCLAW_QA_ALLOW_INSECURE_HTTP=1` 允许在仅限本地开发时使用 loopback `http://` Convex URL。 -正常运行中,`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`。 +在正常运行中,`OPENCLAW_QA_CONVEX_SITE_URL` 应使用 `https://`。 -维护者管理命令(池添加/删除/列出)需要 -`OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 +维护者管理命令(池添加 / 删除 / 列表)必须显式使用 `OPENCLAW_QA_CONVEX_SECRET_MAINTAINER`。 供维护者使用的 CLI 辅助命令: @@ -176,87 +146,87 @@ pnpm openclaw qa credentials list --kind telegram pnpm openclaw qa credentials remove --credential-id ``` -在脚本和 CI 工具中可使用 `--json` 获取机器可读输出。 +在脚本和 CI 工具中,使用 `--json` 获取机器可读输出。 默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`): - `POST /acquire` - 请求:`{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs }` - 成功:`{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? }` - - 资源耗尽/可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` + - 资源耗尽 / 可重试:`{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }` - `POST /heartbeat` - 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs }` - - 成功:`{ status: "ok" }`(或空 `2xx`) + - 成功:`{ status: "ok" }`(或空的 `2xx`) - `POST /release` - 请求:`{ kind, ownerId, actorRole, credentialId, leaseToken }` - - 成功:`{ status: "ok" }`(或空 `2xx`) -- `POST /admin/add`(仅 maintainer secret) + - 成功:`{ status: "ok" }`(或空的 `2xx`) +- `POST /admin/add`(仅限 maintainer 密钥) - 请求:`{ kind, actorId, payload, note?, status? }` - 成功:`{ status: "ok", credential }` -- `POST /admin/remove`(仅 maintainer secret) +- `POST /admin/remove`(仅限 maintainer 密钥) - 请求:`{ credentialId, actorId }` - 成功:`{ status: "ok", changed, credential }` - 活跃租约保护:`{ status: "error", code: "LEASE_ACTIVE", ... }` -- `POST /admin/list`(仅 maintainer secret) +- `POST /admin/list`(仅限 maintainer 密钥) - 请求:`{ kind?, status?, includePayload?, limit? }` - 成功:`{ status: "ok", credentials, count }` -Telegram 类型的载荷形状: +Telegram 类型的 payload 结构: - `{ groupId: string, driverToken: string, sutToken: string }` -- `groupId` 必须是 Telegram 数字聊天 ID 字符串。 -- `admin/add` 会对 `kind: "telegram"` 的该形状进行验证,并拒绝格式错误的载荷。 +- `groupId` 必须是 Telegram chat id 的数字字符串。 +- `admin/add` 会对 `kind: "telegram"` 校验此结构,并拒绝格式错误的 payload。 -### 向 QA 中添加一个渠道 +### 向 QA 添加一个渠道 -向 Markdown QA 系统中添加一个渠道只需要且仅需要两样东西: +向 markdown QA 系统添加一个渠道,严格只需要两样东西: 1. 该渠道的传输适配器。 -2. 一组用于验证该渠道契约的场景包。 +2. 一个用于验证渠道契约的场景包。 -如果共享的 `qa-lab` 主机能够承载流程,就不要新增一个顶层 QA 命令根。 +如果共享的 `qa-lab` 主机可以承载整个流程,就不要新增顶层 QA 命令根节点。 -`qa-lab` 负责共享主机机制: +`qa-lab` 负责共享的主机机制: - `openclaw qa` 命令根 -- 套件启动与关闭 +- 测试套件启动与清理 - worker 并发 -- 产物写入 +- 制品写入 - 报告生成 - 场景执行 -- 对旧 `qa-channel` 场景的兼容性别名 +- 对旧版 `qa-channel` 场景的兼容别名 运行器插件负责传输契约: -- `openclaw qa ` 如何挂载在共享 `qa` 根下 -- 如何为该传输配置 Gateway 网关 +- `openclaw qa ` 如何挂载到共享的 `qa` 根节点下 +- 如何为该传输协议配置 Gateway 网关 - 如何检查就绪状态 - 如何注入入站事件 -- 如何观察出站消息 -- 如何暴露转录和规范化后的传输状态 -- 如何执行由传输支撑的动作 -- 如何处理传输特定的重置或清理 +- 如何观测出站消息 +- 如何暴露 transcript 和规范化后的传输状态 +- 如何执行由传输协议支撑的动作 +- 如何处理传输协议特定的重置或清理 -为新渠道设置的最低采纳门槛是: +新渠道接入的最低门槛是: -1. 保持由 `qa-lab` 持有共享的 `qa` 根。 -2. 在共享的 `qa-lab` 主机接缝上实现传输运行器。 -3. 将传输特定机制保留在运行器插件或渠道 harness 内部。 -4. 将运行器挂载为 `openclaw qa `,而不是注册一个竞争性的根命令。 - 运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。 - 保持 `runtime-api.ts` 轻量;惰性 CLI 和运行器执行应放在单独入口点之后。 -5. 在按主题组织的 `qa/scenarios/` 目录下编写或适配 Markdown 场景。 -6. 对新场景使用通用场景辅助工具。 -7. 除非仓库正在进行有意迁移,否则应保持现有兼容性别名继续工作。 +1. 继续由 `qa-lab` 作为共享 `qa` 根节点的所有者。 +2. 在共享的 `qa-lab` 主机接缝上实现该传输运行器。 +3. 将传输协议特定机制保留在运行器插件或渠道 harness 内部。 +4. 将运行器挂载为 `openclaw qa `,而不是注册一个相互竞争的根命令。 + 运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并在 `runtime-api.ts` 中导出匹配的 `qaRunnerCliRegistrations` 数组。 + 保持 `runtime-api.ts` 轻量;惰性 CLI 和运行器执行应保留在独立入口点之后。 +5. 在带主题的 `qa/scenarios/` 目录下编写或改造 markdown 场景。 +6. 为新场景使用通用场景辅助函数。 +7. 除非仓库正在进行有意的迁移,否则保持现有兼容别名继续可用。 -决策规则是严格的: +决策规则很严格: -- 如果某个行为能在 `qa-lab` 中表达一次,就放到 `qa-lab` 中。 -- 如果某个行为依赖于单一渠道传输,就将其保留在对应运行器插件或插件 harness 中。 -- 如果一个场景需要新增的能力可被多个渠道使用,应添加通用辅助工具,而不是在 `suite.ts` 中添加某个渠道专用分支。 -- 如果某个行为仅对某一种传输有意义,就保持该场景为传输专用,并在场景契约中明确指出。 +- 如果某个行为可以在 `qa-lab` 中一次性表达,就把它放进 `qa-lab`。 +- 如果某个行为依赖某一种渠道传输协议,就把它保留在该运行器插件或插件 harness 中。 +- 如果某个场景需要一种可供多个渠道使用的新能力,就添加一个通用辅助函数,而不是在 `suite.ts` 中添加渠道特定分支。 +- 如果某个行为只对一种传输协议有意义,就让该场景保持传输协议特定,并在场景契约中明确说明。 -新场景推荐使用的通用辅助工具名称为: +新场景推荐使用的通用辅助函数名称是: - `waitForTransportReady` - `waitForChannelReady` @@ -271,7 +241,7 @@ Telegram 类型的载荷形状: - `formatTransportTranscript` - `resetTransport` -现有场景仍可使用兼容性别名,包括: +现有场景仍可使用兼容别名,包括: - `waitForQaChannelReady` - `waitForOutboundMessage` @@ -279,133 +249,119 @@ Telegram 类型的载荷形状: - `formatConversationTranscript` - `resetBus` -新的渠道工作应使用通用辅助工具名称。 -兼容性别名的存在是为了避免一次性强制迁移,而不是为 -新场景编写树立模板。 +新的渠道工作应使用通用辅助函数名称。 +兼容别名的存在是为了避免一次性迁移,而不是作为新场景编写的范式。 -## 测试套件(分别在哪里运行) +## 测试套件(各自在哪里运行) -可以把这些测试套件理解为“现实性逐步增强”(同时也意味着更高的脆弱性/成本): +可以把这些测试套件理解为“真实度逐步增加”(同时波动性 / 成本也逐步增加): -### 单元 / 集成(默认) +### Unit / integration(默认) - 命令:`pnpm test` -- 配置:未定向运行会使用 `vitest.full-*.config.ts` 分片集,并可能将多项目分片展开为按项目划分的配置,以便并行调度 -- 文件:位于 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` node 测试中的 core/unit 清单 +- 配置:未定向的运行使用 `vitest.full-*.config.ts` 分片集合,并且可能会将多项目分片展开为按项目划分的配置,以便进行并行调度 +- 文件:位于 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts` 下的 core / unit 清单,以及由 `vitest.unit.config.ts` 覆盖的白名单 `ui` Node 测试 - 范围: - 纯单元测试 - 进程内集成测试(Gateway 网关认证、路由、工具、解析、配置) - - 针对已知缺陷的确定性回归测试 + - 已知缺陷的确定性回归测试 - 预期: - - 会在 CI 中运行 + - 在 CI 中运行 - 不需要真实密钥 - 应该快速且稳定 - - 未定向的 `pnpm test` 会运行十二个较小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这样可以降低高负载机器上的 RSS 峰值,并避免 auto-reply/extension 工作拖累无关套件。 - `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环并不现实。 - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先将显式文件/目录目标路由到带作用域的通道,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 无需承担完整根项目启动成本。 - 当变更只涉及可路由的源码/测试文件时,`pnpm test:changed` 会将 git 变更路径展开到相同的带作用域通道;而配置/设置编辑仍会回退到更广泛的根项目重跑。 - `pnpm check:changed` 是针对窄范围工作的常规智能本地门禁。它会将 diff 分类为 core、core tests、extensions、extension tests、apps、docs、发布元数据和工具,然后运行匹配的 typecheck/lint/test 通道。公共 Plugin SDK 和插件契约变更会包含 extension 验证,因为 extensions 依赖这些核心契约。仅发布元数据的版本号变更会运行定向的版本/配置/根依赖检查,而不是完整套件,并带有一个防护机制,用于拒绝除顶层版本字段外的 package 变更。 - 来自 agents、commands、plugins、auto-reply 辅助工具、`plugin-sdk` 以及类似纯工具区域的轻导入单元测试,会路由到 `unit-fast` 通道,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有通道中。 - 某些 `plugin-sdk` 和 `commands` 辅助源码文件在 changed-mode 运行中也会映射到这些轻量通道中的显式同级测试,因此修改辅助工具时无需为该目录重跑完整重型套件。 - `auto-reply` 有三个专用桶:顶层 core 辅助工具、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树。这可以让最重的 reply harness 工作避开廉价的 status/chunk/token 测试。 + - 未定向的 `pnpm test` 运行使用十二个更小的分片配置(`core-unit-fast`、`core-unit-src`、`core-unit-security`、`core-unit-ui`、`core-unit-support`、`core-support-boundary`、`core-contracts`、`core-bundled`、`core-runtime`、`agentic`、`auto-reply`、`extensions`),而不是一个巨大的原生根项目进程。这样可以降低高负载机器上的 RSS 峰值,并避免 auto-reply / extension 工作挤占无关测试套件。 - `pnpm test --watch` 仍然使用原生根 `vitest.config.ts` 项目图,因为多分片 watch 循环并不现实。 - `pnpm test`、`pnpm test:watch` 和 `pnpm test:perf:imports` 会先通过带作用域的通道来路由显式的文件 / 目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 不必承担完整根项目启动的成本。 - 当变更仅涉及可路由的源码 / 测试文件时,`pnpm test:changed` 会将变更的 git 路径展开为相同的带作用域通道;配置 / setup 编辑仍会回退到更广泛的根项目重跑。 - `pnpm check:changed` 是窄范围工作时的常规智能本地门禁。它会将 diff 分类为 core、core tests、extensions、extension tests、apps、docs、发布元数据和工具,然后运行匹配的 typecheck / lint / test 通道。公开的插件 SDK 和 plugin-contract 变更会包含 extension 验证,因为 extensions 依赖这些 core 契约。仅包含发布元数据的版本号变更会运行有针对性的 version / config / root-dependency 检查,而不是完整测试套件,并带有一个守卫,用于拒绝顶层 version 字段之外的 package 变更。 - 来自 agents、commands、plugins、auto-reply helpers、`plugin-sdk` 以及类似纯工具区域的轻导入单元测试,会通过 `unit-fast` 通道运行,该通道会跳过 `test/setup-openclaw-runtime.ts`;而有状态 / 运行时负担较重的文件则仍留在现有通道中。 - 选定的 `plugin-sdk` 和 `commands` 辅助源码文件也会在 changed 模式下,将运行映射到这些轻量通道中的显式同级测试,因此 helper 编辑无需为该目录重跑完整的重型测试套件。 - `auto-reply` 有三个专用分桶:顶层 core helpers、顶层 `reply.*` 集成测试,以及 `src/auto-reply/reply/**` 子树。这让最重的 reply harness 工作不会压到廉价的 status / chunk / token 测试上。 - - - 当你修改消息工具发现输入或压缩总结运行时 - 上下文时,请同时保持两个层级的覆盖。 - - 为纯路由和规范化边界添加有针对性的辅助工具回归测试。 - - 保持嵌入式运行器集成套件健康: + + - 当你修改 message-tool 发现输入或压缩运行时上下文时,要同时保留两个层级的覆盖。 + - 为纯路由与规范化边界添加聚焦的 helper 回归测试。 + - 保持嵌入式运行器集成测试套件健康: `src/agents/pi-embedded-runner/compact.hooks.test.ts`、 `src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` 和 `src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`。 - - 这些套件会验证带作用域 ID 和压缩总结行为仍然通过真实的 `run.ts` / `compact.ts` 路径流动;仅有辅助工具测试并不足以替代这些集成路径。 + - 这些测试套件用于验证带作用域的 id 和压缩行为仍会流经真实的 `run.ts` / `compact.ts` 路径;仅有 helper 测试并不能充分替代这些集成路径。 - - 基础 Vitest 配置默认使用 `threads`。 - - 共享 Vitest 配置会固定 `isolate: false`,并在根项目、e2e 和 live 配置中使用非隔离运行器。 - - 根 UI 通道会保留其 `jsdom` 设置和优化器,但也运行在共享的非隔离运行器上。 - - 每个 `pnpm test` 分片都会从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。 - - `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node - 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。 - 如需与原生 V8 行为对比,可设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 + - 基础 Vitest 配置默认为 `threads`。 + - 共享 Vitest 配置固定使用 `isolate: false`,并在根项目、e2e 和 live 配置中使用非隔离运行器。 + - 根 UI 通道保留其 `jsdom` setup 和优化器,但也运行在共享的非隔离运行器上。 + - 每个 `pnpm test` 分片都从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。 + - `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。若要与原生 V8 行为进行对比,请设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1`。 - - `pnpm changed:lanes` 会显示某个 diff 会触发哪些架构通道。 - - pre-commit hook 会在已暂存的格式化/lint 之后运行 `pnpm check:changed --staged`,因此仅 core 的提交不会承担 extension 测试成本,除非它们触及面向 extension 的公共契约。仅发布元数据的提交仍会走定向的版本/配置/根依赖通道。 - - 如果完全相同的已暂存变更集已经通过了同等或更强门禁验证,可使用 - `scripts/committer --fast "" ` 来仅跳过 - changed-scope hook 重跑。已暂存的格式化/lint 仍然会运行。请在交接中说明已完成的门禁。这在某个隔离的 flaky hook 失败被重跑并以带作用域的证据通过后,同样是可接受的。 - - 当变更路径能清晰映射到较小套件时,`pnpm test:changed` 会路由到带作用域的通道。 - - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同路由 - 行为,只是使用更高的 worker 上限。 - - 本地 worker 自动扩缩容刻意保持保守,并会在主机负载平均值已经较高时自动回退,因此默认情况下多个并发 Vitest 运行带来的损害更小。 - - 基础 Vitest 配置会将项目/配置文件标记为 - `forceRerunTriggers`,以确保当测试接线发生变化时,changed-mode 重跑仍然正确。 - - 在受支持主机上,配置会保持 `OPENCLAW_VITEST_FS_MODULE_CACHE` 启用;如果你希望为直接性能分析指定一个显式缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 + - `pnpm changed:lanes` 会显示某个 diff 触发了哪些架构通道。 + - pre-commit hook 会在暂存的格式化 / lint 之后运行 `pnpm check:changed --staged`,因此纯 core 提交无需承担 extension 测试成本,除非它们触及面向 extension 的公开契约。仅包含发布元数据的提交会保留在有针对性的 version / config / root-dependency 通道中。 + - 如果完全相同的暂存变更集已经通过了同等或更严格的门禁验证,可使用 `scripts/committer --fast "" ` 仅跳过 changed-scope hook 的重复运行。暂存的 format / lint 仍会运行。请在交接中说明已完成的门禁。这同样适用于单独重跑后通过的偶发 hook 失败,并附带带作用域的证明。 + - 当变更路径可以清晰映射到更小的测试套件时,`pnpm test:changed` 会通过带作用域通道来路由。 + - `pnpm test:max` 和 `pnpm test:changed:max` 保持相同的路由行为,只是使用更高的 worker 上限。 + - 本地 worker 自动扩缩容刻意保持保守;当主机负载平均值已经很高时会自动回退,因此默认情况下多个并发 Vitest 运行造成的影响更小。 + - 基础 Vitest 配置会将项目 / 配置文件标记为 `forceRerunTriggers`,以便在测试布线发生变化时,changed 模式重跑仍然正确。 + - 该配置会在受支持主机上保持 `OPENCLAW_VITEST_FS_MODULE_CACHE` 启用;如果你想为直接性能分析指定一个明确的缓存位置,请设置 `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`。 - - `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告,以及 - 导入明细输出。 - - `pnpm test:perf:imports:changed` 会将相同的性能分析视图限定到 - 自 `origin/main` 以来发生变更的文件。 - - `pnpm test:perf:changed:bench -- --ref ` 会针对某个已提交 diff,将路由后的 - `test:changed` 与原生根项目路径进行比较,并输出墙钟时间以及 macOS 最大 RSS。 - - `pnpm test:perf:changed:bench -- --worktree` 会通过 - `scripts/test-projects.mjs` 和根 Vitest 配置,将当前脏工作树的变更文件列表进行路由并做性能基准。 - - `pnpm test:perf:profile:main` 会为 - Vitest/Vite 启动和 transform 开销写入主线程 CPU profile。 - - `pnpm test:perf:profile:runner` 会在禁用文件级并行的情况下,为 - 单元测试套件写入运行器 CPU+heap profiles。 + - `pnpm test:perf:imports` 会启用 Vitest 的导入时长报告以及导入明细输出。 + - `pnpm test:perf:imports:changed` 会将同样的性能分析视图限定为自 `origin/main` 以来发生变更的文件。 + - `pnpm test:perf:changed:bench -- --ref ` 会将带路由的 `test:changed` 与该已提交 diff 的原生根项目路径进行比较,并输出 wall time 与 macOS 最大 RSS。 + - `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到 `scripts/test-projects.mjs` 和根 Vitest 配置,对当前未提交工作树进行基准测试。 + - `pnpm test:perf:profile:main` 会写出一份主线程 CPU profile,用于分析 Vitest / Vite 启动与转换开销。 + - `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为 unit 测试套件写出运行器 CPU + heap profile。 ### 稳定性(Gateway 网关) - 命令:`pnpm test:stability:gateway` -- 配置:`vitest.gateway.config.ts`,强制单 worker +- 配置:`vitest.gateway.config.ts`,强制使用一个 worker - 范围: - 启动一个真实的 loopback Gateway 网关,并默认启用诊断 - - 通过诊断事件路径驱动合成的 Gateway 网关消息、memory 和大载荷抖动 + - 通过诊断事件路径驱动合成的 gateway message、memory 和大 payload 抖动 - 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability` - - 覆盖诊断稳定性 bundle 持久化辅助工具 - - 断言记录器保持有界、合成 RSS 样本保持在压力预算之下,并且每会话队列深度最终回落到零 + - 覆盖诊断稳定性 bundle 持久化辅助函数 + - 断言记录器保持有界,合成 RSS 采样保持在压力预算之下,且每个会话的队列深度会回落到零 - 预期: - - 对 CI 安全,且不需要密钥 - - 这是一个用于稳定性回归跟进的窄通道,而不是完整 Gateway 网关套件的替代品 + - 可安全用于 CI,且无需密钥 + - 这是一个用于稳定性回归跟进的窄通道,不是完整 Gateway 网关测试套件的替代品 -### E2E(Gateway 网关 smoke) +### E2E(Gateway 网关冒烟) - 命令:`pnpm test:e2e` - 配置:`vitest.e2e.config.ts` - 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试 - 运行时默认值: - - 使用 Vitest `threads`,并设置 `isolate: false`,与仓库其余部分保持一致。 + - 使用 Vitest `threads` 且 `isolate: false`,与仓库其余部分保持一致。 - 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。 - - 默认以静默模式运行,以减少控制台 I/O 开销。 -- 有用的覆盖项: - - `OPENCLAW_E2E_WORKERS=`:强制设置 worker 数量(上限 16)。 - - `OPENCLAW_E2E_VERBOSE=1`:重新启用详细控制台输出。 + - 默认以 silent 模式运行,以减少控制台 I/O 开销。 +- 常用覆盖项: + - `OPENCLAW_E2E_WORKERS=` 用于强制指定 worker 数量(上限为 16)。 + - `OPENCLAW_E2E_VERBOSE=1` 用于重新启用详细的控制台输出。 - 范围: - 多实例 Gateway 网关端到端行为 - - WebSocket/HTTP 表面、节点配对,以及更重的网络场景 + - WebSocket / HTTP 接口、节点配对以及更重的网络行为 - 预期: - - 会在 CI 中运行(当管线启用时) + - 会在 CI 中运行(当流水线中启用时) - 不需要真实密钥 - - 比单元测试有更多活动部件(可能更慢) + - 比 unit 测试包含更多可变部件(可能更慢) -### E2E:OpenShell 后端 smoke +### E2E:OpenShell 后端冒烟测试 - 命令:`pnpm test:e2e:openshell` - 文件:`extensions/openshell/src/backend.e2e.test.ts` - 范围: - 通过 Docker 在主机上启动一个隔离的 OpenShell Gateway 网关 - - 从一个临时本地 Dockerfile 创建沙箱 - - 通过真实的 `sandbox ssh-config` + SSH exec,对 OpenClaw 的 OpenShell 后端进行测试 - - 通过沙箱 fs bridge 验证远程权威文件系统行为 + - 从一个临时的本地 Dockerfile 创建一个沙箱 + - 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端 + - 通过沙箱 fs bridge 验证远端规范文件系统行为 - 预期: - 仅按需启用;不属于默认的 `pnpm test:e2e` 运行 - - 需要本地 `openshell` CLI 以及可用的 Docker daemon + - 需要本地 `openshell` CLI 和可用的 Docker daemon - 使用隔离的 `HOME` / `XDG_CONFIG_HOME`,然后销毁测试 Gateway 网关和沙箱 -- 有用的覆盖项: - - `OPENCLAW_E2E_OPENSHELL=1`:手动运行更广泛 e2e 套件时启用该测试 - - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`:指向非默认 CLI 二进制或包装脚本 +- 常用覆盖项: + - `OPENCLAW_E2E_OPENSHELL=1`,在手动运行更广泛的 e2e 测试套件时启用该测试 + - `OPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell`,用于指向非默认的 CLI 二进制或包装脚本 ### Live(真实提供商 + 真实模型) @@ -414,141 +370,141 @@ Telegram 类型的载荷形状: - 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件 live 测试 - 默认:由 `pnpm test:live` **启用**(会设置 `OPENCLAW_LIVE_TEST=1`) - 范围: - - “这个提供商/模型今天是否真的能在真实凭证下工作?” + - “这个提供商 / 模型 _今天_ 配合真实凭证是否真的可用?” - 捕获提供商格式变更、工具调用怪癖、认证问题以及速率限制行为 - 预期: - - 本身并非为 CI 稳定性而设计(真实网络、真实提供商策略、配额、故障) + - 按设计不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障) - 会花钱 / 消耗速率限制 - - 应优先运行收窄后的子集,而不是“一次跑全部” -- Live 运行会 source `~/.profile` 以拾取缺失的 API 密钥。 -- 默认情况下,live 运行仍会隔离 `HOME`,并将配置/认证材料复制到一个临时测试 home 中,以避免单元测试 fixture 修改你的真实 `~/.openclaw`。 -- 仅当你明确希望 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 -- `pnpm test:live` 现在默认使用更安静的模式:它会保留 `[live] ...` 进度输出,但会抑制额外的 `~/.profile` 提示,并静音 Gateway 网关启动日志/Bonjour 杂音。如果你希望恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 -- API 密钥轮换(按提供商区分):设置 `*_API_KEYS`,使用逗号/分号格式,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),或者通过 `OPENCLAW_LIVE_*_KEY` 进行每次 live 运行的覆盖;测试在遇到速率限制响应时会重试。 -- 进度/heartbeat 输出: - - Live 套件现在会将进度行输出到 stderr,这样即使 Vitest 控制台捕获较安静,长时间的提供商调用也能明显显示仍在运行。 - - `vitest.live.config.ts` 会禁用 Vitest 的控制台拦截,因此提供商/Gateway 网关的进度行会在 live 运行期间立即流出。 - - 可使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model heartbeat。 - - 可使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 Gateway 网关/探测 heartbeat。 + - 优先运行缩小范围的子集,而不是“全部” +- live 运行会读取 `~/.profile` 以获取缺失的 API 密钥。 +- 默认情况下,live 运行仍会隔离 `HOME`,并将配置 / 认证材料复制到临时测试 home 中,这样 unit fixture 就无法修改你真实的 `~/.openclaw`。 +- 仅当你明确需要 live 测试使用真实 home 目录时,才设置 `OPENCLAW_LIVE_USE_REAL_HOME=1`。 +- `pnpm test:live` 现在默认使用更安静的模式:会保留 `[live] ...` 进度输出,但会隐藏额外的 `~/.profile` 提示,并静音 gateway 启动日志 / Bonjour 噪声。如果你想恢复完整启动日志,请设置 `OPENCLAW_LIVE_TEST_QUIET=0`。 +- API 密钥轮换(按提供商区分):使用逗号 / 分号格式的 `*_API_KEYS`,或使用 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可通过 `OPENCLAW_LIVE_*_KEY` 为单次 live 运行覆盖;测试在遇到速率限制响应时会重试。 +- 进度 / 心跳输出: + - live 测试套件现在会将进度行输出到 stderr,因此即便 Vitest 控制台捕获较安静,长时间的提供商调用也能显示为仍在运行。 + - `vitest.live.config.ts` 会禁用 Vitest 的控制台拦截,因此提供商 / gateway 的进度行会在 live 运行期间立即流式输出。 + - 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整 direct-model 心跳。 + - 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 gateway / probe 心跳。 ## 我应该运行哪个测试套件? -使用下面的决策表: +请使用以下决策表: -- 编辑逻辑/测试:运行 `pnpm test`(如果改动较多,也运行 `pnpm test:coverage`) -- 修改 Gateway 网关网络 / WS 协议 / 配对:额外运行 `pnpm test:e2e` -- 调试“我的机器人挂了” / 提供商特定故障 / 工具调用:运行收窄后的 `pnpm test:live` +- 编辑逻辑 / 测试:运行 `pnpm test`(如果你改动很多,也运行 `pnpm test:coverage`) +- 触及 gateway 网络 / WS 协议 / 配对:追加运行 `pnpm test:e2e` +- 调试“我的 bot 宕了” / 提供商特定故障 / 工具调用:运行缩小范围的 `pnpm test:live` ## Live:Android 节点能力扫描 - 测试:`src/gateway/android-node.capabilities.live.test.ts` - 脚本:`pnpm android:test:integration` -- 目标:调用某个已连接 Android 节点**当前声明的每一个命令**,并断言命令契约行为。 +- 目标:调用已连接 Android 节点当前**声明的每个命令**,并断言命令契约行为。 - 范围: - - 预置/手动设置(该套件不会安装/运行/配对应用)。 - - 针对所选 Android 节点逐命令验证 Gateway 网关 `node.invoke`。 -- 必需的预先设置: - - Android 应用已连接并配对到 Gateway 网关。 - - 应用保持前台运行。 - - 对你预期能够通过的能力,已授予权限/捕获同意。 -- 可选目标覆盖项: + - 预设条件 / 手动 setup(该测试套件不会安装 / 运行 / 配对应用)。 + - 针对选定 Android 节点逐命令验证 gateway `node.invoke`。 +- 必需的预先 setup: + - Android 应用已连接并与 gateway 完成配对。 + - 应用保持在前台。 + - 已授予你期望通过的能力所需的权限 / 捕获同意。 +- 可选目标覆盖: - `OPENCLAW_ANDROID_NODE_ID` 或 `OPENCLAW_ANDROID_NODE_NAME`。 - `OPENCLAW_ANDROID_GATEWAY_URL` / `OPENCLAW_ANDROID_GATEWAY_TOKEN` / `OPENCLAW_ANDROID_GATEWAY_PASSWORD`。 -- 完整 Android 设置详情: [Android App](/zh-CN/platforms/android) +- 完整 Android setup 详情:[Android App](/zh-CN/platforms/android) -## Live:模型 smoke(profile keys) +## Live:模型冒烟测试(profile keys) -Live 测试分为两层,以便隔离故障: +live 测试分为两层,以便我们隔离故障: -- “直接模型”告诉我们,在给定密钥下,提供商/模型是否至少能回复。 -- “Gateway 网关 smoke”告诉我们,针对该模型的完整 Gateway 网关 + 智能体流水线是否工作正常(会话、历史、工具、沙箱策略等)。 +- “Direct model” 告诉我们该提供商 / 模型在给定密钥下是否至少能够响应。 +- “Gateway smoke” 告诉我们完整的 gateway + 智能体流水线是否适用于该模型(会话、历史记录、工具、沙箱策略等)。 -### 第 1 层:直接模型补全(无 Gateway 网关) +### 第 1 层:Direct model completion(无 gateway) - 测试:`src/agents/models.profiles.live.test.ts` - 目标: - - 枚举已发现的模型 - - 使用 `getApiKeyForModel` 选择你具备凭证的模型 - - 对每个模型运行一个小型补全(以及在需要时的定向回归) -- 启用方式: - - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) -- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,是 modern 的别名)才会真正运行该套件;否则它会跳过,以便让 `pnpm test:live` 聚焦于 Gateway 网关 smoke + - 枚举发现到的模型 + - 使用 `getApiKeyForModel` 选择你拥有凭证的模型 + - 为每个模型运行一个小型 completion(并在需要时运行有针对性的回归测试) +- 如何启用: + - `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) +- 设置 `OPENCLAW_LIVE_MODELS=modern`(或 `all`,它是 modern 的别名)即可实际运行该测试套件;否则会跳过,以便让 `pnpm test:live` 聚焦于 gateway 冒烟测试 - 如何选择模型: - - `OPENCLAW_LIVE_MODELS=modern`:运行 modern 允许列表(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - - `OPENCLAW_LIVE_MODELS=all` 是 modern 允许列表的别名 - - 或使用 `OPENCLAW_LIVE_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,..."`(逗号分隔允许列表) - - modern/all 扫描默认带有一个精心挑选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可运行完整 modern 扫描,或设置一个正数以限制为更小的上限。 + - `OPENCLAW_LIVE_MODELS=modern` 运行 modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) + - `OPENCLAW_LIVE_MODELS=all` 是 modern allowlist 的别名 + - 或者 `OPENCLAW_LIVE_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,..."`(逗号分隔的 allowlist) + - modern / all 扫描默认使用精心筛选的高信号上限;设置 `OPENCLAW_LIVE_MAX_MODELS=0` 可进行穷尽式 modern 扫描,或设置为正数以使用更小的上限。 - 如何选择提供商: - - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔允许列表) + - `OPENCLAW_LIVE_PROVIDERS="google,google-antigravity,google-gemini-cli"`(逗号分隔的 allowlist) - 密钥来源: - - 默认:profile store 和环境变量回退 - - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅使用 profile store** -- 该层存在的原因: - - 将“提供商 API 挂了 / 密钥无效”与“Gateway 网关智能体流水线挂了”分离开 - - 容纳小而隔离的回归用例(例如:OpenAI Responses/Codex Responses 的推理回放 + 工具调用流程) + - 默认:profile store 和环境变量后备 + - 设置 `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制**仅**使用 profile store +- 这一层存在的原因: + - 将“提供商 API 损坏 / 密钥无效”与“gateway 智能体流水线损坏”区分开 + - 容纳小型、隔离的回归测试(示例:OpenAI Responses / Codex Responses 的推理重放 + 工具调用流程) -### 第 2 层:Gateway 网关 + dev 智能体 smoke(也就是 `@openclaw` 实际会做的事) +### 第 2 层:Gateway 网关 + dev 智能体冒烟测试(也就是 “@openclaw” 实际执行的内容) - 测试:`src/gateway/gateway-models.profiles.live.test.ts` - 目标: - - 启动一个进程内 Gateway 网关 - - 创建/修补一个 `agent:dev:*` 会话(每次运行按模型覆盖) - - 遍历带密钥的模型,并断言: - - 存在“有意义”的回复(无工具) - - 一个真实工具调用可用(read 探测) - - 可选的额外工具探测可用(exec+read 探测) - - OpenAI 回归路径(仅工具调用 → 后续)保持正常 -- 探测细节(这样你可以快速解释故障): - - `read` 探测:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它并回显 nonce。 - - `exec+read` 探测:测试会要求智能体通过 `exec` 将 nonce 写入临时文件,然后再 `read` 回来。 - - image 探测:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 + - 启动一个进程内 gateway + - 创建 / 修补一个 `agent:dev:*` 会话(每次运行按模型覆盖) + - 遍历带密钥的模型并断言: + - “有意义的”响应(无工具) + - 一次真实工具调用可正常工作(read probe) + - 可选的额外工具探测(exec+read probe) + - OpenAI 回归路径(仅工具调用 → 后续跟进)继续正常工作 +- Probe 细节(这样你可以快速解释失败原因): + - `read` probe:测试会在工作区写入一个 nonce 文件,并要求智能体 `read` 它,然后把 nonce 回显出来。 + - `exec+read` probe:测试会要求智能体通过 `exec` 将 nonce 写入一个临时文件,然后再 `read` 回来。 + - image probe:测试会附加一个生成的 PNG(猫 + 随机代码),并期望模型返回 `cat `。 - 实现参考:`src/gateway/gateway-models.profiles.live.test.ts` 和 `src/gateway/live-image-probe.ts`。 -- 启用方式: - - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) +- 如何启用: + - `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) - 如何选择模型: - - 默认:modern 允许列表(Opus/Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) - - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是 modern 允许列表的别名 - - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)来收窄范围 - - modern/all Gateway 网关扫描默认带有一个精心挑选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可运行完整 modern 扫描,或设置一个正数以限制为更小的上限。 -- 如何选择提供商(避免“OpenRouter 全家桶”): - - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔允许列表) -- 该 live 测试始终启用工具 + 图像探测: - - `read` 探测 + `exec+read` 探测(工具压力测试) - - 当模型声明支持图像输入时会运行图像探测 - - 流程(高层): - - 测试生成一个带有 “CAT” + 随机代码的小 PNG(`src/gateway/live-image-probe.ts`) + - 默认:modern allowlist(Opus / Sonnet 4.6+、GPT-5.x + Codex、Gemini 3、GLM 4.7、MiniMax M2.7、Grok 4) + - `OPENCLAW_LIVE_GATEWAY_MODELS=all` 是 modern allowlist 的别名 + - 或设置 `OPENCLAW_LIVE_GATEWAY_MODELS="provider/model"`(或逗号列表)以缩小范围 + - modern / all gateway 扫描默认使用精心筛选的高信号上限;设置 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=0` 可进行穷尽式 modern 扫描,或设置为正数以使用更小的上限。 +- 如何选择提供商(避免“OpenRouter 所有东西”): + - `OPENCLAW_LIVE_GATEWAY_PROVIDERS="google,google-antigravity,google-gemini-cli,openai,anthropic,zai,minimax"`(逗号分隔的 allowlist) +- 工具 + 图像探测在此 live 测试中始终启用: + - `read` probe + `exec+read` probe(工具压力测试) + - 当模型声明支持图像输入时运行 image probe + - 流程(高层概述): + - 测试生成一个带有 “CAT” + 随机代码的小型 PNG(`src/gateway/live-image-probe.ts`) - 通过 `agent` `attachments: [{ mimeType: "image/png", content: "" }]` 发送 - - Gateway 网关会将附件解析到 `images[]` 中(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) + - Gateway 网关将附件解析到 `images[]` 中(`src/gateway/server-methods/agent.ts` + `src/gateway/chat-attachments.ts`) - 嵌入式智能体将多模态用户消息转发给模型 - - 断言:回复中包含 `cat` + 该代码(OCR 容错:允许轻微错误) + - 断言:回复包含 `cat` + 该代码(OCR 容错:允许轻微错误) -提示:若要查看你机器上可以测试什么(以及精确的 `provider/model` ID),请运行: +提示:若要查看你的机器上可以测试什么内容(以及确切的 `provider/model` id),请运行: ```bash openclaw models list openclaw models list --json ``` -## Live:CLI 后端 smoke(Claude、Codex、Gemini 或其他本地 CLI) +## Live:CLI 后端冒烟测试(Claude、Codex、Gemini 或其他本地 CLI) - 测试:`src/gateway/gateway-cli-backend.live.test.ts` -- 目标:在不触碰默认配置的情况下,使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线。 -- 后端特定的 smoke 默认值位于所属 extension 的 `cli-backend.ts` 定义中。 +- 目标:使用本地 CLI 后端验证 Gateway 网关 + 智能体流水线,同时不触碰你的默认配置。 +- 后端特定的默认冒烟设置位于所属 extension 的 `cli-backend.ts` 定义中。 - 启用方式: - - `pnpm test:live`(或直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) + - `pnpm test:live`(或在直接调用 Vitest 时设置 `OPENCLAW_LIVE_TEST=1`) - `OPENCLAW_LIVE_CLI_BACKEND=1` - 默认值: - - 默认提供商/模型:`claude-cli/claude-sonnet-4-6` - - 命令/参数/图像行为来自所属 CLI 后端插件元数据。 + - 默认 provider / model:`claude-cli/claude-sonnet-4-6` + - command / args / image 行为来自所属 CLI 后端插件元数据。 - 覆盖项(可选): - `OPENCLAW_LIVE_CLI_BACKEND_MODEL="codex-cli/gpt-5.5"` - `OPENCLAW_LIVE_CLI_BACKEND_COMMAND="/full/path/to/codex"` - `OPENCLAW_LIVE_CLI_BACKEND_ARGS='["exec","--json","--color","never","--sandbox","read-only","--skip-git-repo-check"]'` - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1`:发送真实图像附件(路径会注入到提示词中)。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"`:将图像文件路径作为 CLI 参数传递,而不是注入提示词。 - - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`):当设置了 `IMAGE_ARG` 时,用于控制图像参数传递方式。 - - `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1`:发送第二轮并验证恢复流程。 - - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0`:禁用默认的 Claude Sonnet -> Opus 同会话连续性探测(当所选模型支持切换目标时,设置为 `1` 可强制启用)。 + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_PROBE=1` 用于发送真实图像附件(路径会注入到提示词中)。 + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_ARG="--image"` 用于把图像文件路径作为 CLI 参数传递,而不是注入到提示词中。 + - `OPENCLAW_LIVE_CLI_BACKEND_IMAGE_MODE="repeat"`(或 `"list"`)用于在设置 `IMAGE_ARG` 时控制图像参数的传递方式。 + - `OPENCLAW_LIVE_CLI_BACKEND_RESUME_PROBE=1` 用于发送第二轮并验证恢复流程。 + - `OPENCLAW_LIVE_CLI_BACKEND_MODEL_SWITCH_PROBE=0` 用于禁用默认的 Claude Sonnet -> Opus 同会话连续性 probe(当所选模型支持切换目标时,设置为 `1` 可强制启用)。 示例: @@ -558,13 +514,13 @@ OPENCLAW_LIVE_CLI_BACKEND=1 \ pnpm test:live src/gateway/gateway-cli-backend.live.test.ts ``` -Docker 配方: +Docker 用法: ```bash pnpm test:docker:live-cli-backend ``` -单提供商 Docker 配方: +单提供商 Docker 用法: ```bash pnpm test:docker:live-cli-backend:claude @@ -576,26 +532,26 @@ pnpm test:docker:live-cli-backend:gemini 说明: - Docker 运行器位于 `scripts/test-live-cli-backend-docker.sh`。 -- 它会在仓库 Docker 镜像中,以非 root 的 `node` 用户运行 live CLI-backend smoke。 -- 它会从所属 extension 解析 CLI smoke 元数据,然后将匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到一个可缓存的可写前缀 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 中(默认:`~/.cache/openclaw/docker-cli-tools`)。 -- `pnpm test:docker:live-cli-backend:claude-subscription` 需要可移植的 Claude Code 订阅 OAuth,可通过 `~/.claude/.credentials.json` 中的 `claudeAiOauth.subscriptionType` 或来自 `claude setup-token` 的 `CLAUDE_CODE_OAUTH_TOKEN` 提供。它会先证明 Docker 中直接 `claude -p` 可用,然后在不保留 Anthropic API 密钥环境变量的情况下,运行两个 Gateway 网关 CLI-backend 轮次。该订阅通道默认禁用 Claude MCP/tool 和图像探测,因为 Claude 目前会将第三方应用使用计入额外使用量计费,而不是正常订阅计划配额。 -- Live CLI-backend smoke 现在会对 Claude、Codex 和 Gemini 运行相同的端到端流程:文本轮次、图像分类轮次,然后通过 Gateway 网关 CLI 验证 MCP `cron` 工具调用。 -- Claude 的默认 smoke 还会将会话从 Sonnet 切换为 Opus,并验证恢复后的会话仍记得之前的备注。 +- 它会在仓库 Docker 镜像中以非 root 的 `node` 用户身份运行 live CLI 后端冒烟测试。 +- 它会从所属 extension 解析 CLI 冒烟测试元数据,然后将匹配的 Linux CLI 包(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)安装到位于 `OPENCLAW_DOCKER_CLI_TOOLS_DIR` 的可写缓存前缀中(默认:`~/.cache/openclaw/docker-cli-tools`)。 +- `pnpm test:docker:live-cli-backend:claude-subscription` 需要通过 `~/.claude/.credentials.json` 中带有 `claudeAiOauth.subscriptionType` 的便携式 Claude Code 订阅 OAuth,或通过 `claude setup-token` 生成的 `CLAUDE_CODE_OAUTH_TOKEN`。它会先在 Docker 中验证直接 `claude -p` 可用,然后在不保留 Anthropic API 密钥环境变量的情况下运行两轮 Gateway 网关 CLI 后端交互。此订阅通道默认禁用 Claude MCP / 工具与图像探测,因为 Claude 当前会将第三方应用使用计入额外使用计费,而不是普通订阅计划额度。 +- 现在的 live CLI 后端冒烟测试会对 Claude、Codex 和 Gemini 执行相同的端到端流程:文本轮次、图像分类轮次,然后通过 gateway CLI 验证 MCP `cron` 工具调用。 +- Claude 的默认冒烟测试还会将会话从 Sonnet 修补到 Opus,并验证恢复后的会话仍记得先前的备注。 -## Live:ACP 绑定 smoke(`/acp spawn ... --bind here`) +## Live:ACP 绑定冒烟测试(`/acp spawn ... --bind here`) - 测试:`src/gateway/gateway-acp-bind.live.test.ts` -- 目标:使用真实 ACP 智能体验证真实的 ACP conversation-bind 流程: +- 目标:使用 live ACP 智能体验证真实的 ACP 会话绑定流程: - 发送 `/acp spawn --bind here` - - 在原地绑定一个合成的 message-channel 会话 - - 在同一会话上发送一个正常的后续消息 - - 验证该后续消息落入绑定的 ACP 会话转录中 -- 启用方式: + - 就地绑定一个合成的消息渠道会话 + - 在同一会话上发送一次普通后续消息 + - 验证该后续消息会落入已绑定的 ACP 会话 transcript 中 +- 启用: - `pnpm test:live src/gateway/gateway-acp-bind.live.test.ts` - `OPENCLAW_LIVE_ACP_BIND=1` - 默认值: - Docker 中的 ACP 智能体:`claude,codex,gemini` - - 直接 `pnpm test:live ...` 使用的 ACP 智能体:`claude` + - 用于直接 `pnpm test:live ...` 的 ACP 智能体:`claude` - 合成渠道:Slack 私信风格的会话上下文 - ACP 后端:`acpx` - 覆盖项: @@ -607,8 +563,8 @@ pnpm test:docker:live-cli-backend:gemini - `OPENCLAW_LIVE_ACP_BIND_CODEX_MODEL=gpt-5.5` - `OPENCLAW_LIVE_ACP_BIND_PARENT_MODEL=openai/gpt-5.4` - 说明: - - 该通道使用 Gateway 网关 `chat.send` 表面,并带有仅管理员可用的合成 originating-route 字段,这样测试就可以附加 message-channel 上下文,而无需伪装为真实外部投递。 - - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会为所选 ACP harness 智能体使用内置 `acpx` 插件的内置智能体注册表。 + - 此通道使用 gateway `chat.send` 接口,并带有仅管理员可用的合成 originating-route 字段,这样测试就可以附加消息渠道上下文,而无需假装进行外部投递。 + - 当未设置 `OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND` 时,测试会使用内置 `acpx` 插件中为所选 ACP harness 智能体提供的内建智能体注册表。 示例: @@ -618,13 +574,13 @@ OPENCLAW_LIVE_ACP_BIND=1 \ pnpm test:live src/gateway/gateway-acp-bind.live.test.ts ``` -Docker 配方: +Docker 用法: ```bash pnpm test:docker:live-acp-bind ``` -单智能体 Docker 配方: +单智能体 Docker 用法: ```bash pnpm test:docker:live-acp-bind:claude @@ -635,35 +591,33 @@ pnpm test:docker:live-acp-bind:gemini Docker 说明: - Docker 运行器位于 `scripts/test-live-acp-bind-docker.sh`。 -- 默认情况下,它会依次针对所有受支持的 live CLI 智能体运行 ACP 绑定 smoke:`claude`、`codex`,然后 `gemini`。 -- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可收窄矩阵。 -- 它会 source `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,将 `acpx` 安装到一个可写 npm 前缀中,然后在缺失时安装所请求的 live CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。 -- 在 Docker 内部,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,以便 acpx 保持从已 source 的 profile 中获得的提供商环境变量对子 harness CLI 可用。 +- 默认情况下,它会按顺序针对所有受支持的 live CLI 智能体运行 ACP 绑定冒烟测试:`claude`、`codex`,然后是 `gemini`。 +- 使用 `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`、`OPENCLAW_LIVE_ACP_BIND_AGENTS=codex` 或 `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini` 可缩小矩阵范围。 +- 它会读取 `~/.profile`,将匹配的 CLI 认证材料暂存到容器中,把 `acpx` 安装到一个可写的 npm 前缀中,然后在缺失时安装所请求的 live CLI(`@anthropic-ai/claude-code`、`@openai/codex` 或 `@google/gemini-cli`)。 +- 在 Docker 内,运行器会设置 `OPENCLAW_LIVE_ACP_BIND_ACPX_COMMAND=$HOME/.npm-global/bin/acpx`,从而让 acpx 保持可从已读取的 profile 中获取提供商环境变量,并传递给子 harness CLI。 -## Live:Codex app-server harness smoke +## Live:Codex app-server harness 冒烟测试 -- 目标:通过常规 Gateway 网关 - `agent` 方法验证插件持有的 Codex harness: - - 加载内置 `codex` 插件 +- 目标:通过常规 gateway + `agent` 方法验证由插件拥有的 Codex harness: + - 加载内置的 `codex` 插件 - 选择 `OPENCLAW_AGENT_RUNTIME=codex` - - 在强制使用 Codex harness 的情况下,向 `openai/gpt-5.5` 发送第一次 Gateway 网关智能体轮次 - - 向同一 OpenClaw 会话发送第二轮,并验证 app-server - 线程能够恢复 - - 通过同一 Gateway 网关命令 - 路径运行 `/codex status` 和 `/codex models` - - 可选运行两个经过 Guardian 审查的提权 shell 探测:一个应被批准的无害命令,以及一个应被拒绝并要求智能体回问的伪造秘密上传命令 + - 使用强制启用 Codex harness 的方式,向 `openai/gpt-5.5` 发送第一轮 gateway 智能体消息 + - 向同一个 OpenClaw 会话发送第二轮消息,并验证 app-server 线程可以恢复 + - 通过相同的 gateway 命令路径运行 `/codex status` 和 `/codex models` + - 可选地运行两个经过 Guardian 审核的提权 shell 探测:一个应被批准的无害命令,以及一个应被拒绝的伪造密钥上传操作,以便智能体回问用户 - 测试:`src/gateway/gateway-codex-harness.live.test.ts` - 启用:`OPENCLAW_LIVE_CODEX_HARNESS=1` - 默认模型:`openai/gpt-5.5` - 可选图像探测:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=1` -- 可选 MCP/tool 探测:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` +- 可选 MCP / 工具探测:`OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=1` - 可选 Guardian 探测:`OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=1` -- 该 smoke 会设置 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,因此损坏的 Codex - harness 无法通过静默回退到 PI 来“蒙混过关”。 -- 认证:来自 shell/profile 的 `OPENAI_API_KEY`,以及可选复制的 +- 此冒烟测试会设置 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,因此损坏的 Codex + harness 不会通过静默回退到 PI 而误通过。 +- 认证:来自 shell / profile 的 `OPENAI_API_KEY`,外加可选复制的 `~/.codex/auth.json` 和 `~/.codex/config.toml` -本地配方: +本地用法: ```bash source ~/.profile @@ -675,7 +629,7 @@ OPENCLAW_LIVE_CODEX_HARNESS=1 \ pnpm test:live -- src/gateway/gateway-codex-harness.live.test.ts ``` -Docker 配方: +Docker 用法: ```bash source ~/.profile @@ -685,65 +639,65 @@ pnpm test:docker:live-codex-harness Docker 说明: - Docker 运行器位于 `scripts/test-live-codex-harness-docker.sh`。 -- 它会 source 挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI +- 它会读取挂载的 `~/.profile`,传递 `OPENAI_API_KEY`,在存在时复制 Codex CLI 认证文件,将 `@openai/codex` 安装到一个可写、已挂载的 npm - 前缀中,暂存源码树,然后只运行 Codex-harness live 测试。 -- Docker 默认启用图像、MCP/tool 和 Guardian 探测。若需更窄范围的调试运行,请设置 + 前缀中,暂存源码树,然后只运行 Codex harness live 测试。 +- Docker 默认启用图像、MCP / 工具和 Guardian 探测。若你需要更窄范围的调试运行,可设置 `OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0` 或 `OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0` 或 `OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0`。 - Docker 还会导出 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`,与 live - 测试配置保持一致,因此旧版别名或 PI 回退无法掩盖 Codex harness + 测试配置保持一致,这样旧别名或回退到 PI 就无法掩盖 Codex harness 回归问题。 -### 推荐的 live 配方 +### 推荐的 live 用法 -范围收窄且显式的允许列表最快、也最不容易抖动: +缩小范围且明确的 allowlist 最快,也最不容易波动: -- 单模型,直接模式(无 Gateway 网关): +- 单模型,direct(无 gateway): - `OPENCLAW_LIVE_MODELS="openai/gpt-5.5" pnpm test:live src/agents/models.profiles.live.test.ts` -- 单模型,Gateway 网关 smoke: +- 单模型,gateway 冒烟测试: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - 跨多个提供商的工具调用: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -- Google 聚焦(Gemini API key + Antigravity): - - Gemini(API key):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` +- 聚焦 Google(Gemini API 密钥 + Antigravity): + - Gemini(API 密钥):`OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Antigravity(OAuth):`OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` 说明: -- `google/...` 使用 Gemini API(API key)。 -- `google-antigravity/...` 使用 Antigravity OAuth bridge(Cloud Code Assist 风格的智能体端点)。 -- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的认证 + 工具怪癖)。 +- `google/...` 使用 Gemini API(API 密钥)。 +- `google-antigravity/...` 使用 Antigravity OAuth 桥接(Cloud Code Assist 风格的智能体端点)。 +- `google-gemini-cli/...` 使用你机器上的本地 Gemini CLI(单独的认证 + 工具行为差异)。 - Gemini API 与 Gemini CLI: - - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API key / profile 认证);这通常是大多数用户所说的 “Gemini”。 - - CLI:OpenClaw 会调用本地 `gemini` 二进制;它有自己的认证方式,并且行为可能不同(流式传输/工具支持/版本偏差)。 + - API:OpenClaw 通过 HTTP 调用 Google 托管的 Gemini API(API 密钥 / profile 认证);大多数用户说的 “Gemini” 指的就是这个。 + - CLI:OpenClaw 会 shell out 到本地 `gemini` 二进制;它有自己的认证方式,行为也可能不同(流式传输 / 工具支持 / 版本偏差)。 ## Live:模型矩阵(我们覆盖什么) -这里没有固定的“CI 模型列表”(live 是按需启用的),但以下是在拥有密钥的开发机器上,**建议**定期覆盖的模型。 +没有固定的“CI 模型列表”(live 是按需启用的),但对于在开发机器上持有密钥的情况,下面这些是建议定期覆盖的模型。 -### 现代 smoke 集(工具调用 + 图像) +### Modern 冒烟测试集合(工具调用 + 图像) -这是我们期望持续可用的“常见模型”运行集: +这是我们预期应持续可用的“常见模型”运行集合: - OpenAI(非 Codex):`openai/gpt-5.5`(可选:`openai/gpt-5.4-mini`) -- OpenAI Codex OAuth:`openai/gpt-5.5`(`openai-codex/gpt-*` 仍保留为旧版别名) +- OpenAI Codex OAuth:`openai/gpt-5.5`(`openai-codex/gpt-*` 仍是旧版别名) - Anthropic:`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`) -- Google(Gemini API):`google/gemini-3.1-pro-preview` 和 `google/gemini-3-flash-preview`(避免较旧的 Gemini 2.x 模型) +- Google(Gemini API):`google/gemini-3.1-pro-preview` 和 `google/gemini-3-flash-preview`(避免使用较旧的 Gemini 2.x 模型) - Google(Antigravity):`google-antigravity/claude-opus-4-6-thinking` 和 `google-antigravity/gemini-3-flash` - Z.AI(GLM):`zai/glm-4.7` - MiniMax:`minimax/MiniMax-M2.7` -使用工具 + 图像运行 Gateway 网关 smoke: +运行带工具 + 图像的 gateway 冒烟测试: `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,zai/glm-4.7,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` -### 基线:工具调用(Read + 可选 Exec) +### Baseline:工具调用(Read + 可选 Exec) -每个提供商家族至少选一个: +每个提供商家族至少选择一个: - OpenAI:`openai/gpt-5.5`(或 `openai/gpt-5.4-mini`) - Anthropic:`anthropic/claude-opus-4-6`(或 `anthropic/claude-sonnet-4-6`) @@ -753,49 +707,49 @@ Docker 说明: 可选的额外覆盖(有更好,没有也行): -- xAI:`xai/grok-4`(或当前最新可用) +- xAI:`xai/grok-4`(或最新可用版本) - Mistral:`mistral/`…(选择一个你已启用、支持工具的模型) -- Cerebras:`cerebras/`…(如果你有权限) +- Cerebras:`cerebras/`…(如果你有访问权限) - LM Studio:`lmstudio/`…(本地;工具调用取决于 API 模式) ### Vision:图像发送(附件 → 多模态消息) -至少在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中包含一个支持图像的模型(Claude/Gemini/OpenAI 支持视觉的变体等),以运行图像探测。 +在 `OPENCLAW_LIVE_GATEWAY_MODELS` 中至少包含一个支持图像的模型(Claude / Gemini / OpenAI 的视觉变体等),以运行图像探测。 ### 聚合器 / 替代 Gateway 网关 -如果你启用了相应密钥,我们也支持通过以下方式测试: +如果你已启用相关密钥,我们也支持通过以下方式测试: - OpenRouter:`openrouter/...`(数百个模型;使用 `openclaw models scan` 查找支持工具 + 图像的候选项) -- OpenCode:Zen 使用 `opencode/...`,Go 使用 `opencode-go/...`(认证通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY`) +- OpenCode:`opencode/...` 用于 Zen,`opencode-go/...` 用于 Go(通过 `OPENCODE_API_KEY` / `OPENCODE_ZEN_API_KEY` 认证) -如果你有凭证/配置,也可以将更多提供商纳入 live 矩阵: +你还可以将更多提供商纳入 live 矩阵中(如果你有凭证 / 配置): - 内置:`openai`、`openai-codex`、`anthropic`、`google`、`google-vertex`、`google-antigravity`、`google-gemini-cli`、`zai`、`openrouter`、`opencode`、`opencode-go`、`xai`、`groq`、`cerebras`、`mistral`、`github-copilot` -- 通过 `models.providers`(自定义端点):`minimax`(云/API),以及任何兼容 OpenAI/Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) +- 通过 `models.providers`(自定义端点):`minimax`(云 / API),以及任何兼容 OpenAI / Anthropic 的代理(LM Studio、vLLM、LiteLLM 等) -提示:不要试图在文档中硬编码“所有模型”。权威列表始终是你机器上的 `discoverModels(...)` 返回结果,以及当前可用的密钥。 +提示:不要尝试在文档中硬编码“所有模型”。权威列表应始终以你机器上 `discoverModels(...)` 的返回结果,以及当前可用的密钥为准。 -## 凭证(切勿提交) +## 凭证(绝不要提交) -Live 测试发现凭证的方式与 CLI 完全相同。实际含义是: +live 测试发现凭证的方式与 CLI 完全一致。实际含义如下: -- 如果 CLI 能工作,live 测试通常也应能找到相同的密钥。 -- 如果 live 测试说“没有凭证”,请按调试 `openclaw models list` / 模型选择的方式来调试。 +- 如果 CLI 可用,live 测试应能找到相同的密钥。 +- 如果 live 测试提示 “no creds”,就像调试 `openclaw models list` / 模型选择那样去调试。 -- 每个智能体的认证配置文件:`~/.openclaw/agents//agent/auth-profiles.json`(这就是 live 测试中“profile keys”的含义) +- 按智能体划分的认证 profile:`~/.openclaw/agents//agent/auth-profiles.json`(这就是 live 测试中所说的 “profile keys”) - 配置:`~/.openclaw/openclaw.json`(或 `OPENCLAW_CONFIG_PATH`) -- 旧版状态目录:`~/.openclaw/credentials/`(存在时会复制到暂存的 live home 中,但它不是主要的 profile-key 存储) -- 默认情况下,live 本地运行会将当前活动配置、每个智能体的 `auth-profiles.json` 文件、旧版 `credentials/` 以及受支持的外部 CLI 认证目录复制到临时测试 home 中;暂存的 live home 会跳过 `workspace/` 和 `sandboxes/`,并剥离 `agents.*.workspace` / `agentDir` 路径覆盖项,以确保探测不会落到你的真实主机工作区上。 +- 旧版状态目录:`~/.openclaw/credentials/`(存在时会被复制到暂存的 live home 中,但它不是主 profile-key 存储) +- 默认情况下,本地 live 运行会将当前活动配置、按智能体划分的 `auth-profiles.json` 文件、旧版 `credentials/` 目录以及受支持的外部 CLI 认证目录复制到一个临时测试 home 中;暂存的 live home 会跳过 `workspace/` 和 `sandboxes/`,并移除 `agents.*.workspace` 与 `agentDir` 路径覆盖,以确保探测不会落到你真实主机的工作区上。 -如果你希望依赖环境变量密钥(例如导出在你的 `~/.profile` 中),请在 `source ~/.profile` 之后再运行本地测试,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载进容器)。 +如果你想依赖环境变量中的密钥(例如导出在你的 `~/.profile` 中),请在本地测试前先运行 `source ~/.profile`,或者使用下面的 Docker 运行器(它们可以将 `~/.profile` 挂载到容器中)。 ## Deepgram live(音频转录) - 测试:`extensions/deepgram/audio.live.test.ts` - 启用:`DEEPGRAM_API_KEY=... DEEPGRAM_LIVE_TEST=1 pnpm test:live extensions/deepgram/audio.live.test.ts` -## BytePlus coding plan live +## BytePlus(国际版) 编码计划 live - 测试:`extensions/byteplus/live.test.ts` - 启用:`BYTEPLUS_API_KEY=... BYTEPLUS_LIVE_TEST=1 pnpm test:live extensions/byteplus/live.test.ts` @@ -807,8 +761,8 @@ Live 测试发现凭证的方式与 CLI 完全相同。实际含义是: - 启用:`OPENCLAW_LIVE_TEST=1 COMFY_LIVE_TEST=1 pnpm test:live -- extensions/comfy/comfy.live.test.ts` - 范围: - 运行内置 comfy 图像、视频和 `music_generate` 路径 - - 除非已配置 `models.providers.comfy.`,否则会跳过各项能力 - - 适用于在修改 comfy 工作流提交、轮询、下载或插件注册后进行验证 + - 如果未配置 `models.providers.comfy.`,则跳过对应能力 + - 适用于修改 comfy 工作流提交、轮询、下载或插件注册之后 ## 图像生成 live @@ -817,27 +771,27 @@ Live 测试发现凭证的方式与 CLI 完全相同。实际含义是: - Harness:`pnpm test:live:media image` - 范围: - 枚举每个已注册的图像生成提供商插件 - - 在探测前,从你的登录 shell(`~/.profile`)中加载缺失的提供商环境变量 - - 默认优先使用 live/env API 密钥,而不是已存储的认证配置文件,这样 `auth-profiles.json` 中陈旧的测试密钥不会掩盖真实 shell 凭证 - - 跳过没有可用认证/profile/model 的提供商 + - 在探测前从你的登录 shell(`~/.profile`)中加载缺失的提供商环境变量 + - 默认优先使用 live / 环境变量 API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证 + - 跳过没有可用认证 / profile / 模型的提供商 - 通过共享运行时能力运行标准图像生成变体: - `google:flash-generate` - `google:pro-generate` - `google:pro-edit` - `openai:default-generate` -- 当前覆盖的内置提供商: +- 当前已覆盖的内置提供商: - `fal` - `google` - `minimax` - `openai` - `vydra` - `xai` -- 可选收窄: +- 可选缩小范围: - `OPENCLAW_LIVE_IMAGE_GENERATION_PROVIDERS="openai,google,xai"` - `OPENCLAW_LIVE_IMAGE_GENERATION_MODELS="openai/gpt-image-2,google/gemini-3.1-flash-image-preview,xai/grok-imagine-image"` - `OPENCLAW_LIVE_IMAGE_GENERATION_CASES="google:flash-generate,google:pro-edit,xai:default-generate,xai:default-edit"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile-store 认证,并忽略仅来自环境变量的覆盖项 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile store 认证,并忽略仅来自环境变量的覆盖 ## 音乐生成 live @@ -847,21 +801,21 @@ Live 测试发现凭证的方式与 CLI 完全相同。实际含义是: - 范围: - 运行共享的内置音乐生成提供商路径 - 当前覆盖 Google 和 MiniMax - - 在探测前,从你的登录 shell(`~/.profile`)中加载提供商环境变量 - - 默认优先使用 live/env API 密钥,而不是已存储的认证配置文件,这样 `auth-profiles.json` 中陈旧的测试密钥不会掩盖真实 shell 凭证 - - 跳过没有可用认证/profile/model 的提供商 - - 在可用时,运行两个已声明的运行时模式: - - `generate`,仅提示词输入 + - 在探测前从你的登录 shell(`~/.profile`)中加载提供商环境变量 + - 默认优先使用 live / 环境变量 API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证 + - 跳过没有可用认证 / profile / 模型的提供商 + - 在可用时运行两种已声明的运行时模式: + - `generate`,仅使用提示词输入 - 当提供商声明 `capabilities.edit.enabled` 时运行 `edit` - 当前共享通道覆盖: - `google`:`generate`、`edit` - `minimax`:`generate` - - `comfy`:使用独立的 Comfy live 文件,不属于此共享扫描 -- 可选收窄: + - `comfy`:使用单独的 Comfy live 文件,不在此共享扫描中 +- 可选缩小范围: - `OPENCLAW_LIVE_MUSIC_GENERATION_PROVIDERS="google,minimax"` - `OPENCLAW_LIVE_MUSIC_GENERATION_MODELS="google/lyria-3-clip-preview,minimax/music-2.5+"` - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile-store 认证,并忽略仅来自环境变量的覆盖项 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile store 认证,并忽略仅来自环境变量的覆盖 ## 视频生成 live @@ -870,189 +824,178 @@ Live 测试发现凭证的方式与 CLI 完全相同。实际含义是: - Harness:`pnpm test:live:media video` - 范围: - 运行共享的内置视频生成提供商路径 - - 默认采用发布安全的 smoke 路径:非 FAL 提供商、每个提供商一个 text-to-video 请求、一秒钟龙虾提示词,以及由 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 控制的每提供商操作上限(默认 `180000`) - - 默认跳过 FAL,因为提供商侧队列延迟可能主导发布时间;如需显式运行,请传入 `--video-providers fal` 或 `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` - - 在探测前,从你的登录 shell(`~/.profile`)中加载提供商环境变量 - - 默认优先使用 live/env API 密钥,而不是已存储的认证配置文件,这样 `auth-profiles.json` 中陈旧的测试密钥不会掩盖真实 shell 凭证 - - 跳过没有可用认证/profile/model 的提供商 - - 默认只运行 `generate` - - 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1`,可在可用时额外运行已声明的转换模式: - - 当提供商声明 `capabilities.imageToVideo.enabled`,并且所选提供商/模型在共享扫描中接受基于 buffer 的本地图像输入时,运行 `imageToVideo` - - 当提供商声明 `capabilities.videoToVideo.enabled`,并且所选提供商/模型在共享扫描中接受基于 buffer 的本地视频输入时,运行 `videoToVideo` - - 当前在共享扫描中已声明但被跳过的 `imageToVideo` 提供商: - - `vydra`,因为内置 `veo3` 仅支持文本,内置 `kling` 则需要远程图像 URL + - 默认使用对发布安全的冒烟路径:非 FAL 提供商、每个提供商一次 text-to-video 请求、一秒钟的龙虾提示词,以及来自 `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` 的每提供商操作上限(默认 `180000`) + - 默认跳过 FAL,因为提供商侧队列延迟可能主导发布时间;传入 `--video-providers fal` 或 `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` 可显式运行它 + - 在探测前从你的登录 shell(`~/.profile`)中加载提供商环境变量 + - 默认优先使用 live / 环境变量 API 密钥,而不是已存储的认证 profile,因此 `auth-profiles.json` 中过期的测试密钥不会掩盖真实的 shell 凭证 + - 跳过没有可用认证 / profile / 模型的提供商 + - 默认仅运行 `generate` + - 设置 `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` 可在可用时也运行已声明的变换模式: + - 当提供商声明 `capabilities.imageToVideo.enabled` 且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地图像输入时,运行 `imageToVideo` + - 当提供商声明 `capabilities.videoToVideo.enabled` 且所选提供商 / 模型在共享扫描中接受基于 buffer 的本地视频输入时,运行 `videoToVideo` + - 当前在共享扫描中已声明但跳过的 `imageToVideo` 提供商: + - `vydra`,因为内置 `veo3` 仅支持文本,而内置 `kling` 需要远程图像 URL - 提供商特定的 Vydra 覆盖: - `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_VYDRA_VIDEO=1 pnpm test:live -- extensions/vydra/vydra.live.test.ts` - 该文件会运行 `veo3` text-to-video,以及默认使用远程图像 URL fixture 的 `kling` 通道 - 当前 `videoToVideo` live 覆盖: - 仅 `runway`,且所选模型为 `runway/gen4_aleph` 时 - - 当前在共享扫描中已声明但被跳过的 `videoToVideo` 提供商: - - `alibaba`、`qwen`、`xai`,因为这些路径目前需要远程 `http(s)` / MP4 参考 URL - - `google`,因为当前共享 Gemini/Veo 通道使用本地基于 buffer 的输入,而该路径不被共享扫描接受 - - `openai`,因为当前共享通道缺乏对组织特定视频 inpaint/remix 访问权限的保证 -- 可选收窄: + - 当前在共享扫描中已声明但跳过的 `videoToVideo` 提供商: + - `alibaba`、`qwen`、`xai`,因为这些路径当前需要远程 `http(s)` / MP4 参考 URL + - `google`,因为当前共享的 Gemini / Veo 通道使用基于本地 buffer 的输入,而该路径在共享扫描中不被接受 + - `openai`,因为当前共享通道缺少特定组织的视频 inpaint / remix 访问保证 +- 可选缩小范围: - `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="google,openai,runway"` - `OPENCLAW_LIVE_VIDEO_GENERATION_MODELS="google/veo-3.1-fast-generate-preview,openai/sora-2,runway/gen4_aleph"` - - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 可让默认扫描包含所有提供商,包括 FAL - - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 可降低每个提供商的操作上限,用于激进的 smoke 运行 + - `OPENCLAW_LIVE_VIDEO_GENERATION_SKIP_PROVIDERS=""` 以在默认扫描中包含每个提供商,包括 FAL + - `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS=60000` 可在激进的冒烟测试中降低每个提供商的操作上限 - 可选认证行为: - - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 强制使用 profile-store 认证,并忽略仅来自环境变量的覆盖项 + - `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 可强制使用 profile store 认证,并忽略仅来自环境变量的覆盖 ## 媒体 live harness - 命令:`pnpm test:live:media` - 目的: - - 通过一个仓库原生入口点运行共享的图像、音乐和视频 live 套件 + - 通过一个仓库原生入口点运行共享的图像、音乐和视频 live 测试套件 - 自动从 `~/.profile` 加载缺失的提供商环境变量 - - 默认自动将每个套件收窄到当前具备可用认证的提供商 - - 复用 `scripts/test-live.mjs`,因此 heartbeat 和 quiet 模式行为保持一致 + - 默认自动将每个测试套件缩小到当前具有可用认证的提供商 + - 复用 `scripts/test-live.mjs`,因此心跳和安静模式行为保持一致 - 示例: - `pnpm test:live:media` - `pnpm test:live:media image video --providers openai,google,minimax` - `pnpm test:live:media video --video-providers openai,runway --all-providers` - `pnpm test:live:media music --quiet` -## Docker 运行器(可选的 “在 Linux 上也能工作” 检查) +## Docker 运行器(可选的“可在 Linux 中工作”检查) 这些 Docker 运行器分为两类: -- Live-model 运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 只会在仓库 Docker 镜像中运行各自对应的 profile-key live 文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),同时挂载你的本地配置目录和工作区(若已挂载,也会 source `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 -- Docker live 运行器默认使用更小的 smoke 上限,以确保完整 Docker 扫描仍然可行: - `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,而 +- Live 模型运行器:`test:docker:live-models` 和 `test:docker:live-gateway` 仅在仓库 Docker 镜像内运行各自匹配的 profile-key live 文件(`src/agents/models.profiles.live.test.ts` 和 `src/gateway/gateway-models.profiles.live.test.ts`),同时挂载你的本地配置目录和工作区(如果已挂载,也会读取 `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。 +- Docker live 运行器默认使用较小的冒烟测试上限,以便完整的 Docker 扫描保持可行: + `test:docker:live-models` 默认设置 `OPENCLAW_LIVE_MAX_MODELS=12`,并且 `test:docker:live-gateway` 默认设置 `OPENCLAW_LIVE_GATEWAY_SMOKE=1`、 `OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8`、 `OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000` 和 - `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。如果你明确想运行更大、更完整的扫描,可覆盖这些环境变量。 -- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次 live Docker 镜像,然后将其复用于两个 live Docker 通道。它还会通过 `test:docker:e2e-build` 构建一个共享的 `scripts/e2e/Dockerfile` 镜像,并将其复用于执行已构建应用的 E2E 容器 smoke 运行器。 -- 容器 smoke 运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:gateway-network`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 + `OPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000`。当你 + 明确需要更大、更彻底的扫描时,再覆盖这些环境变量。 +- `test:docker:all` 会先通过 `test:docker:live-build` 构建一次 live Docker 镜像,然后在两个 live Docker 通道中复用它。它还会通过 `test:docker:e2e-build` 构建一个共享的 `scripts/e2e/Dockerfile` 镜像,并在用于验证已构建应用的 E2E 容器冒烟运行器中复用它。 +- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:gateway-network`、`test:docker:mcp-channels`、`test:docker:pi-bundle-mcp-tools`、`test:docker:cron-mcp-cleanup`、`test:docker:plugins`、`test:docker:plugin-update` 和 `test:docker:config-reload` 会启动一个或多个真实容器,并验证更高层级的集成路径。 -Live-model Docker 运行器还会仅绑定挂载所需的 CLI 认证 home(如果运行未收窄,则挂载全部受支持的 home),然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改主机认证存储: +这些 live 模型 Docker 运行器还会仅绑定挂载所需的 CLI 认证 home(如果运行未缩小范围,则挂载所有受支持的认证 home),然后在运行前将它们复制到容器 home 中,这样外部 CLI OAuth 就可以刷新令牌,而不会修改主机的认证存储: -- 直接模型:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) -- ACP 绑定 smoke:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`) -- CLI 后端 smoke:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`) -- Codex app-server harness smoke:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`) +- Direct model:`pnpm test:docker:live-models`(脚本:`scripts/test-live-models-docker.sh`) +- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`) +- CLI 后端冒烟测试:`pnpm test:docker:live-cli-backend`(脚本:`scripts/test-live-cli-backend-docker.sh`) +- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness`(脚本:`scripts/test-live-codex-harness-docker.sh`) - Gateway 网关 + dev 智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`) -- Open WebUI live smoke:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) -- 新手引导向导(TTY,全流程脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`) -- Npm tarball 新手引导/渠道/智能体 smoke:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包后的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,默认再配置 Telegram,验证启用插件会按需安装其运行时依赖,运行 doctor,并执行一次 mock OpenAI 智能体轮次。可通过 `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,通过 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 -- Bun 全局安装 smoke:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离的 home 中使用 `bun install -g` 安装,并验证 `openclaw infer image providers --json` 能返回内置图像提供商,而不是卡住。可通过 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,通过 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建 Docker 镜像中复制 `dist/`。 -- 安装器 Docker smoke:`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。非 root 安装器检查会保持隔离的 npm 缓存,以免 root 持有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root/update/direct-npm 缓存。 +- Open WebUI live 冒烟测试:`pnpm test:docker:openwebui`(脚本:`scripts/e2e/openwebui-docker.sh`) +- 新手引导向导(TTY,完整脚手架):`pnpm test:docker:onboard`(脚本:`scripts/e2e/onboard-docker.sh`) +- Npm tarball 新手引导 / 渠道 / 智能体冒烟测试:`pnpm test:docker:npm-onboard-channel-agent` 会在 Docker 中全局安装打包后的 OpenClaw tarball,通过 env-ref 新手引导配置 OpenAI,并默认配置 Telegram,验证启用插件时会按需安装其运行时依赖,运行 doctor,并执行一次 mock 的 OpenAI 智能体轮次。可通过 `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,通过 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。 +- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前树,在隔离的 home 中通过 `bun install -g` 安装它,并验证 `openclaw infer image providers --json` 会返回内置图像提供商,而不是卡住。可通过 `OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,通过 `OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local` 从已构建的 Docker 镜像复制 `dist/`。 +- 安装器 Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。update 冒烟测试默认使用 npm `latest` 作为稳定基线,然后再升级到候选 tarball。非 root 安装器检查会保留隔离的 npm 缓存,以避免 root 拥有的缓存条目掩盖用户本地安装行为。设置 `OPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache` 可在本地重跑之间复用 root / update / direct-npm 缓存。 +- Install Smoke CI 会通过 `OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1` 跳过重复的 direct-npm 全局更新;当你需要直接 `npm install -g` 覆盖时,请在本地不带该环境变量运行脚本。 - Gateway 网关网络(两个容器,WS 认证 + health):`pnpm test:docker:gateway-network`(脚本:`scripts/e2e/gateway-network-docker.sh`) -- OpenAI Responses web_search 最小推理回归:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会让一个 mock OpenAI 服务器通过 Gateway 网关运行,验证 `web_search` 将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查 Gateway 网关日志中出现原始细节。 -- MCP 渠道 bridge(预置 Gateway 网关 + stdio bridge + 原始 Claude notification-frame smoke):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) -- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow/deny smoke):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`) -- Cron/subagent MCP 清理(真实 Gateway 网关 + 在隔离 cron 和一次性 subagent 运行后回收 stdio MCP 子进程):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`) -- 插件(安装 smoke + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) -- 插件更新未变化 smoke:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`) -- 配置重载元数据 smoke:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) -- 内置插件运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认会构建一个小型 Docker 运行器镜像,在主机上构建并打包一次 OpenClaw,然后将该 tarball 挂载到各个 Linux 安装场景中。可通过 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用该镜像,在新鲜本地构建后通过 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。 -- 迭代时可通过禁用无关场景来收窄内置插件运行时依赖测试,例如: +- OpenAI Responses `web_search` 最小推理回归测试:`pnpm test:docker:openai-web-search-minimal`(脚本:`scripts/e2e/openai-web-search-minimal-docker.sh`)会通过 Gateway 网关运行一个 mock OpenAI 服务器,验证 `web_search` 会将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始细节出现在 Gateway 网关日志中。 +- MCP 渠道桥接(已预置的 Gateway 网关 + stdio bridge + 原始 Claude notification-frame 冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`) +- Pi 内置 MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile allow / deny 冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`) +- Cron / subagent MCP 清理(真实 Gateway 网关 + stdio MCP 子进程,在隔离的 cron 和一次性 subagent 运行后清理):`pnpm test:docker:cron-mcp-cleanup`(脚本:`scripts/e2e/cron-mcp-cleanup-docker.sh`) +- 插件(安装冒烟测试 + `/plugin` 别名 + Claude bundle 重启语义):`pnpm test:docker:plugins`(脚本:`scripts/e2e/plugins-docker.sh`) +- 插件更新无变化冒烟测试:`pnpm test:docker:plugin-update`(脚本:`scripts/e2e/plugin-update-unchanged-docker.sh`) +- 配置热重载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`) +- 内置插件运行时依赖:`pnpm test:docker:bundled-channel-deps` 默认会构建一个小型 Docker 运行器镜像,在主机上构建并打包一次 OpenClaw,然后将该 tarball 挂载到每个 Linux 安装场景中。可通过 `OPENCLAW_SKIP_DOCKER_BUILD=1` 复用镜像,在刚完成一次本地构建后通过 `OPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0` 跳过主机重建,或通过 `OPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 指向现有 tarball。 +- 在迭代时,你可以通过禁用无关场景来缩小内置插件运行时依赖测试范围,例如: `OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps`。 -手动预构建并复用共享的 built-app 镜像: +手动预构建并复用共享 built-app 镜像: ```bash OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local pnpm test:docker:e2e-build OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels ``` -当设置时,像 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 这样的套件专用镜像覆盖项仍然优先。如果 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向的是远程共享镜像,而它本地尚不存在,脚本会先拉取它。QR 和安装器 Docker 测试会保留各自的 Dockerfile,因为它们验证的是打包/安装行为,而不是共享的 built-app 运行时。 +设置后,诸如 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 这类测试套件专用镜像覆盖仍然优先生效。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果本地尚不存在,该脚本会先拉取它。QR 和安装器 Docker 测试继续使用各自独立的 Dockerfile,因为它们验证的是 package / install 行为,而不是共享的 built-app 运行时。 -Live-model Docker 运行器还会以只读方式绑定挂载当前检出, -并在容器内将其暂存到一个临时 workdir 中。这样既能保持运行时 -镜像精简,又能让 Vitest 针对你精确的本地源码/配置运行。 -暂存步骤会跳过大型仅本地缓存和应用构建输出,例如 -`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地 `.build` 或 -Gradle 输出目录,这样 Docker live 运行就不会花费数分钟去复制 -机器特定产物。 -它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,以便 Gateway 网关 live 探测不会在容器内部启动真实的 Telegram/Discord 等渠道 worker。 -`test:docker:live-models` 仍然会运行 `pnpm test:live`,因此当你需要收窄或排除该 Docker 通道中的 Gateway 网关 -live 覆盖时,也请同时传入 `OPENCLAW_LIVE_GATEWAY_*`。 -`test:docker:openwebui` 是一个更高层次的兼容性 smoke:它会启动一个启用了 OpenAI 兼容 HTTP 端点的 OpenClaw Gateway 网关容器, -再针对该 Gateway 网关启动一个固定版本的 Open WebUI 容器,通过 -Open WebUI 完成登录,验证 `/api/models` 暴露出 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一条真实聊天请求。 -首次运行可能明显更慢,因为 Docker 可能需要拉取 -Open WebUI 镜像,而 Open WebUI 也可能需要完成它自己的冷启动设置。 -该通道需要一个可用的 live 模型密钥,而 `OPENCLAW_PROFILE_FILE` +这些 live 模型 Docker 运行器还会以只读方式绑定挂载当前 checkout,并将其暂存到容器内的临时 workdir 中。这样既能保持运行时镜像精简,又能让 Vitest 针对你当前精确的本地源码 / 配置运行。 +暂存步骤会跳过大型本地专用缓存和应用构建输出,例如 +`.pnpm-store`、`.worktrees`、`__openclaw_vitest__`,以及应用本地的 `.build` 或 +Gradle 输出目录,因此 Docker live 运行不会花费数分钟来复制机器特定的制品。 +它们还会设置 `OPENCLAW_SKIP_CHANNELS=1`,这样 gateway live 探测就不会在容器内启动真实的 Telegram / Discord / 等渠道 worker。 +`test:docker:live-models` 仍然会运行 `pnpm test:live`,因此当你需要缩小或排除该 Docker 通道中的 gateway live 覆盖时,也请一并传入 +`OPENCLAW_LIVE_GATEWAY_*`。 +`test:docker:openwebui` 是更高层级的兼容性冒烟测试:它会启动一个启用了 OpenAI 兼容 HTTP 端点的 OpenClaw gateway 容器,再启动一个固定版本的 Open WebUI 容器并将其指向该 gateway,通过 Open WebUI 登录,验证 `/api/models` 会暴露 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一条真实聊天请求。 +首次运行可能明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,而 Open WebUI 也可能需要完成自己的冷启动 setup。 +该通道需要一个可用的 live 模型密钥,`OPENCLAW_PROFILE_FILE` (默认 `~/.profile`)是在 Docker 化运行中提供该密钥的主要方式。 -成功运行会打印一个类似 `{ "ok": true, "model": -"openclaw/default", ... }` 的小 JSON 载荷。 -`test:docker:mcp-channels` 是刻意设计为确定性的,不需要 -真实的 Telegram、Discord 或 iMessage 账户。它会启动一个已预置的 Gateway 网关 -容器,再启动第二个容器来运行 `openclaw mcp serve`,然后 -验证路由后的会话发现、转录读取、附件元数据、 -实时事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 发送的 Claude 风格渠道 + -权限通知。通知检查会直接检查原始 stdio MCP 帧, -因此该 smoke 验证的是 bridge 实际发出的内容,而不仅仅是某个特定客户端 SDK 碰巧暴露出来的内容。 -`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要 live -模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实的 stdio MCP 探测服务器, -通过嵌入式 Pi bundle MCP 运行时实例化该服务器,执行该工具,然后验证 `coding` 和 `messaging` 会保留 +成功运行会输出一个小型 JSON payload,例如 `{ "ok": true, "model": +"openclaw/default", ... }`。 +`test:docker:mcp-channels` 被刻意设计为确定性的,不需要真实的 +Telegram、Discord 或 iMessage 账号。它会启动一个已预置的 Gateway +容器,再启动第二个容器来运行 `openclaw mcp serve`,然后通过真实的 stdio MCP bridge +验证路由后的会话发现、transcript 读取、附件元数据、live 事件队列行为、出站发送路由,以及 Claude 风格的渠道 + +权限通知。通知检查会直接检查原始 stdio MCP frame,因此该冒烟测试验证的是桥接实际发出的内容,而不仅仅是某个特定客户端 SDK 恰好暴露出来的内容。 +`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要 live 模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实 stdio MCP probe 服务器,通过嵌入式 Pi bundle MCP 运行时将该服务器实体化,执行该工具,然后验证 `coding` 和 `messaging` 会保留 `bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会将其过滤掉。 -`test:docker:cron-mcp-cleanup` 是确定性的,不需要 live 模型 -密钥。它会启动一个已预置的 Gateway 网关,并带有真实 stdio MCP 探测服务器,运行一个 -隔离的 cron 轮次和一个 `/subagents spawn` 一次性子轮次,然后验证 -每次运行后 MCP 子进程都会退出。 +`test:docker:cron-mcp-cleanup` 是确定性的,不需要 live 模型密钥。它会启动一个带真实 stdio MCP probe 服务器的已预置 Gateway 网关,运行一次隔离的 cron 轮次和一次 `/subagents spawn` 单次子智能体轮次,然后验证每次运行后 MCP 子进程都会退出。 -手动 ACP 纯语言线程 smoke(不在 CI 中): +手动 ACP 自然语言线程冒烟测试(非 CI): - `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel ...` -- 请保留此脚本用于回归/调试工作流。它未来可能还会用于 ACP 线程路由验证,因此不要删除它。 +- 保留此脚本用于回归 / 调试工作流。将来可能还需要它来验证 ACP 线程路由,因此不要删除它。 有用的环境变量: -- `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`),会挂载到 `/home/node/.openclaw` -- `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`),会挂载到 `/home/node/.openclaw/workspace` -- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`),会挂载到 `/home/node/.profile`,并在运行测试前被 source -- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1`:仅验证从 `OPENCLAW_PROFILE_FILE` source 出来的环境变量,使用临时配置/工作区目录,并且不挂载外部 CLI 认证 -- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`),会挂载到 `/home/node/.npm-global`,用于缓存 Docker 内部安装的 CLI -- `$HOME` 下的外部 CLI 认证目录/文件会以只读方式挂载到 `/host-auth...`,然后在测试开始前复制到 `/home/node/...` +- `OPENCLAW_CONFIG_DIR=...`(默认:`~/.openclaw`)挂载到 `/home/node/.openclaw` +- `OPENCLAW_WORKSPACE_DIR=...`(默认:`~/.openclaw/workspace`)挂载到 `/home/node/.openclaw/workspace` +- `OPENCLAW_PROFILE_FILE=...`(默认:`~/.profile`)挂载到 `/home/node/.profile`,并在运行测试前读取 +- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` 读取的环境变量,此时使用临时配置 / 工作区目录,且不挂载外部 CLI 认证 +- `OPENCLAW_DOCKER_CLI_TOOLS_DIR=...`(默认:`~/.cache/openclaw/docker-cli-tools`)挂载到 `/home/node/.npm-global`,用于 Docker 内缓存 CLI 安装 +- `$HOME` 下的外部 CLI 认证目录 / 文件会以只读方式挂载到 `/host-auth...` 下,然后在测试开始前复制到 `/home/node/...` - 默认目录:`.minimax` - 默认文件:`~/.codex/auth.json`、`~/.codex/config.toml`、`.claude.json`、`~/.claude/.credentials.json`、`~/.claude/settings.json`、`~/.claude/settings.local.json` - - 收窄后的提供商运行只会挂载由 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录/文件 - - 可手动使用 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none` 或逗号列表(如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`)进行覆盖 -- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...`:收窄运行范围 -- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...`:在容器内过滤提供商 -- `OPENCLAW_SKIP_DOCKER_BUILD=1`:复用现有的 `openclaw:local-live` 镜像,用于无需重建的重跑 -- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1`:确保凭证来自 profile store(而非环境变量) -- `OPENCLAW_OPENWEBUI_MODEL=...`:选择 Gateway 网关为 Open WebUI smoke 暴露的模型 -- `OPENCLAW_OPENWEBUI_PROMPT=...`:覆盖 Open WebUI smoke 使用的 nonce 检查提示词 -- `OPENWEBUI_IMAGE=...`:覆盖固定的 Open WebUI 镜像标签 + - 缩小范围后的提供商运行只会挂载根据 `OPENCLAW_LIVE_PROVIDERS` / `OPENCLAW_LIVE_GATEWAY_PROVIDERS` 推断出的所需目录 / 文件 + - 可通过 `OPENCLAW_DOCKER_AUTH_DIRS=all`、`OPENCLAW_DOCKER_AUTH_DIRS=none`,或逗号列表(如 `OPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex`)手动覆盖 +- `OPENCLAW_LIVE_GATEWAY_MODELS=...` / `OPENCLAW_LIVE_MODELS=...` 用于缩小运行范围 +- `OPENCLAW_LIVE_GATEWAY_PROVIDERS=...` / `OPENCLAW_LIVE_PROVIDERS=...` 用于在容器内过滤提供商 +- `OPENCLAW_SKIP_DOCKER_BUILD=1` 用于在无需重建时复用现有 `openclaw:local-live` 镜像 +- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile store(而不是环境变量) +- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择 Gateway 网关对 Open WebUI 冒烟测试暴露的模型 +- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词 +- `OPENWEBUI_IMAGE=...` 用于覆盖固定的 Open WebUI 镜像标签 ## 文档完整性检查 -文档编辑后请运行文档检查:`pnpm check:docs`。 -若还需要检查页内标题锚点,请运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。 +在编辑文档后运行文档检查:`pnpm check:docs`。 +当你还需要页内标题检查时,运行完整的 Mintlify 锚点校验:`pnpm docs:check-links:anchors`。 -## 离线回归(对 CI 安全) +## 离线回归测试(可安全用于 CI) -这些是在没有真实提供商的情况下进行的“真实流水线”回归: +这些是在不使用真实提供商的情况下执行的“真实流水线”回归测试: -- Gateway 网关工具调用(mock OpenAI,真实 Gateway 网关 + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) -- Gateway 网关向导(WS `wizard.start`/`wizard.next`,会写入配置 + 强制认证):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) +- Gateway 网关工具调用(mock OpenAI、真实 gateway + 智能体循环):`src/gateway/gateway.test.ts`(用例:“runs a mock OpenAI tool call end-to-end via gateway agent loop”) +- Gateway 网关向导(WS `wizard.start` / `wizard.next`,强制写入配置 + auth):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”) ## 智能体可靠性评估(Skills) -我们已经有一些对 CI 安全的测试,它们表现得像“智能体可靠性评估”: +我们已经有一些可安全用于 CI 的测试,它们的行为类似“智能体可靠性评估”: -- 通过真实 Gateway 网关 + 智能体循环运行 mock 工具调用(`src/gateway/gateway.test.ts`)。 -- 端到端向导流程,用于验证会话接线和配置效果(`src/gateway/gateway.test.ts`)。 +- 通过真实 gateway + 智能体循环执行 mock 工具调用(`src/gateway/gateway.test.ts`)。 +- 用于验证会话布线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。 -针对 Skills(参见 [Skills](/zh-CN/tools/skills))目前仍缺少的部分: +对于 Skills(参见 [Skills](/zh-CN/tools/skills)),目前仍缺少的是: -- **决策能力:** 当 Skills 被列在提示词中时,智能体是否会选择正确的 skill(或避免无关 skill)? -- **遵循性:** 智能体在使用前是否会读取 `SKILL.md`,并遵循要求的步骤/参数? -- **工作流契约:** 可断言工具顺序、会话历史继承以及沙箱边界的多轮场景。 +- **决策能力:** 当提示词中列出 Skills 时,智能体是否会选择正确的 skill(或避开无关 skill)? +- **合规性:** 智能体是否会在使用前读取 `SKILL.md`,并遵循要求的步骤 / 参数? +- **工作流契约:** 断言工具顺序、会话历史延续以及沙箱边界的多轮场景。 -未来的评估应首先保持确定性: +未来的评估应优先保持确定性: -- 一个使用 mock 提供商的场景运行器,用于断言工具调用 + 调用顺序、skill 文件读取和会话接线。 -- 一个小型的 skill 聚焦场景套件(使用 vs 避免、门控、prompt injection)。 -- 只有在对 CI 安全的套件就位之后,才引入可选的 live 评估(按需启用、受环境变量门控)。 +- 一个使用 mock 提供商的场景运行器,用于断言工具调用及其顺序、skill 文件读取以及会话布线。 +- 一小组聚焦于 skill 的场景(使用 vs 避免、门控、提示词注入)。 +- 仅在可安全用于 CI 的测试套件到位之后,再添加可选的 live 评估(按需启用、由环境变量控制)。 -## 契约测试(插件与渠道形状) +## 契约测试(插件和渠道形状) -契约测试会验证每个已注册插件和渠道是否符合其接口契约。它们会遍历所有已发现的插件,并运行一套形状与行为断言。默认的 `pnpm test` 单元通道会有意跳过这些共享接缝和 smoke 文件;当你修改共享渠道或提供商表面时,请显式运行契约命令。 +契约测试用于验证每个已注册插件和渠道都符合其接口契约。它们会遍历所有已发现的插件,并运行一组针对形状和行为的断言。默认的 `pnpm test` unit 通道会刻意跳过这些共享接缝和冒烟文件;当你修改共享渠道或提供商接口时,请显式运行契约命令。 ### 命令 @@ -1067,12 +1010,12 @@ Open WebUI 镜像,而 Open WebUI 也可能需要完成它自己的冷启动设 - **plugin** - 基本插件形状(id、name、capabilities) - **setup** - 设置向导契约 - **session-binding** - 会话绑定行为 -- **outbound-payload** - 消息载荷结构 +- **outbound-payload** - 消息 payload 结构 - **inbound** - 入站消息处理 - **actions** - 渠道动作处理器 - **threading** - 线程 ID 处理 -- **directory** - 目录/成员列表 API -- **group-policy** - 群组策略强制执行 +- **directory** - 目录 / roster API +- **group-policy** - 群组策略执行 ### 提供商状态契约 @@ -1086,31 +1029,31 @@ Open WebUI 镜像,而 Open WebUI 也可能需要完成它自己的冷启动设 位于 `src/plugins/contracts/*.contract.test.ts`: - **auth** - 认证流程契约 -- **auth-choice** - 认证选择/挑选 +- **auth-choice** - 认证方式选择 - **catalog** - 模型目录 API - **discovery** - 插件发现 - **loader** - 插件加载 - **runtime** - 提供商运行时 -- **shape** - 插件形状/接口 +- **shape** - 插件形状 / 接口 - **wizard** - 设置向导 ### 何时运行 -- 修改 plugin-sdk 导出或子路径后 -- 添加或修改渠道或提供商插件后 -- 重构插件注册或发现逻辑后 +- 修改 plugin-sdk 导出或子路径之后 +- 添加或修改渠道或提供商插件之后 +- 重构插件注册或发现逻辑之后 契约测试会在 CI 中运行,且不需要真实 API 密钥。 ## 添加回归测试(指南) -当你修复了一个在 live 中发现的提供商/模型问题时: +当你修复一个在 live 中发现的提供商 / 模型问题时: -- 如果可能,请添加一个对 CI 安全的回归测试(mock/stub 提供商,或捕获精确的请求形状转换) -- 如果它天然只能通过 live 发现(速率限制、认证策略),请将 live 测试保持为窄范围,并通过环境变量按需启用 -- 优先针对能够捕捉该缺陷的最小层级: - - 提供商请求转换/重放缺陷 → 直接模型测试 - - Gateway 网关会话/历史/工具流水线缺陷 → Gateway 网关 live smoke 或对 CI 安全的 Gateway 网关 mock 测试 -- SecretRef 遍历防护栏: - - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言带遍历段的 exec ids 会被拒绝。 - - 如果你在 `src/secrets/target-registry-data.ts` 中新增了一个 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会有意在遇到未分类目标 id 时失败,因此新类别无法被静默跳过。 +- 如果可能,添加一个可安全用于 CI 的回归测试(mock / stub 提供商,或捕获精确的请求形状转换) +- 如果问题本质上只能在 live 中复现(速率限制、认证策略),则保持 live 测试范围狭窄,并通过环境变量按需启用 +- 优先瞄准能捕获该缺陷的最小层级: + - 提供商请求转换 / 重放缺陷 → direct models 测试 + - gateway 会话 / 历史记录 / 工具流水线缺陷 → gateway live 冒烟测试,或可安全用于 CI 的 gateway mock 测试 +- SecretRef 遍历护栏: + - `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言遍历段 exec id 会被拒绝。 + - 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会在遇到未分类目标 id 时故意失败,以确保新类别不会被静默跳过。 diff --git a/docs/zh-CN/plugins/codex-harness.md b/docs/zh-CN/plugins/codex-harness.md index e13419097..7dc8f9970 100644 --- a/docs/zh-CN/plugins/codex-harness.md +++ b/docs/zh-CN/plugins/codex-harness.md @@ -1,30 +1,24 @@ --- read_when: - - 你想使用内置的 Codex app-server harness + - 你想使用内置的 Codex 应用服务器测试框架 - 你需要 Codex 模型引用和配置示例 - - 你想为仅 Codex 部署禁用 PI 回退 സംവിധ to=final code omitted -summary: 通过内置的 Codex app-server harness 运行 OpenClaw 嵌入式智能体轮次 -title: Codex harness + - 你想为仅使用 Codex 的部署禁用 Pi 回退机制 +summary: 通过内置的 Codex 应用服务器测试框架运行 OpenClaw 嵌入式智能体回合 +title: Codex 测试框架 x-i18n: - generated_at: "2026-04-23T20:56:54Z" + generated_at: "2026-04-23T21:49:32Z" model: gpt-5.4 provider: openai - source_hash: 65e96ac709a7996878037da3ffb8903cdd3ad83bb5de75c47ab2f0a08882098c + source_hash: 27b7b662c5eb2002fed8d2c752c4227a46a89d767ac838138327e64df84e4919 source_path: plugins/codex-harness.md workflow: 15 --- -内置的 `codex` 插件让 OpenClaw 可以通过 -Codex app-server,而不是内置的 PI harness,来运行嵌入式智能体轮次。 +内置的 `codex` 插件让 OpenClaw 可以通过 Codex 应用服务器运行嵌入式智能体回合,而不是使用内置的 Pi 测试框架。 -当你希望由 Codex 接管底层智能体会话时,请使用它:模型 -发现、原生线程恢复、原生压缩总结,以及 app-server 执行。 -OpenClaw 仍然负责聊天渠道、会话文件、模型选择、工具、 -审批、媒体传递,以及可见的转录镜像。 +当你希望由 Codex 接管底层智能体会话时,请使用此功能:模型发现、原生线程恢复、原生压缩,以及应用服务器执行。OpenClaw 仍然负责聊天渠道、会话文件、模型选择、工具、审批、媒体传输,以及可见的转录镜像。 -原生 Codex 轮次同样遵循共享插件 hooks,因此提示词 shim、 -感知压缩总结的自动化、工具中间件以及生命周期观察器都能与 -PI harness 保持一致: +原生 Codex 回合同样会遵循共享的插件钩子,因此提示词 shim、压缩感知自动化、工具中间件和生命周期观察器都能与 Pi 测试框架保持一致: - `before_prompt_build` - `before_compaction`, `after_compaction` @@ -33,57 +27,42 @@ PI harness 保持一致: - `before_message_write` - `agent_end` -内置插件还可以注册 Codex app-server extension factory,以添加 -异步 `tool_result` 中间件。 +内置插件还可以注册一个 Codex 应用服务器扩展工厂,以添加异步 `tool_result` 中间件。 -该 harness 默认关闭。新配置应保持 OpenAI 模型引用 -规范为 `openai/gpt-*`,并在需要原生 app-server 执行时显式强制设置 -`embeddedHarness.runtime: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。 -旧版 `codex/*` 模型引用仍会为兼容性自动选择该 harness。 +该测试框架默认关闭。新配置应将 OpenAI 模型引用规范地保持为 `openai/gpt-*`,并在希望使用原生应用服务器执行时,显式强制设置 `embeddedHarness.runtime: "codex"` 或 `OPENCLAW_AGENT_RUNTIME=codex`。为了兼容性,旧版 `codex/*` 模型引用仍会自动选择该测试框架。 ## 选择正确的模型前缀 -OpenClaw 现在会将 OpenAI GPT 模型引用统一规范为 `openai/*`: +OpenClaw 现在将 OpenAI GPT 模型引用统一规范为 `openai/*`: -| 模型引用 | 运行时路径 | 适用场景 | +| 模型引用 | 运行时路径 | 使用场景 | | ----------------------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------- | -| `openai/gpt-5.5` | 通过 OpenClaw/PI 流程访问 OpenAI 提供商 | 你希望使用 `OPENAI_API_KEY` 直接访问 OpenAI Platform API。 | -| `openai/gpt-5.5` + `embeddedHarness.runtime: "codex"` | Codex app-server harness | 你希望对嵌入式智能体轮次使用原生 Codex app-server 执行。 | +| `openai/gpt-5.5` | 通过 OpenClaw/Pi 管线的 OpenAI 提供商 | 你希望使用 `OPENAI_API_KEY` 直接访问 OpenAI Platform API。 | +| `openai/gpt-5.5` + `embeddedHarness.runtime: "codex"` | Codex 应用服务器测试框架 | 你希望嵌入式智能体回合使用原生 Codex 应用服务器执行。 | -旧版 `openai-codex/gpt-*` 和 `codex/gpt-*` 引用仍然接受作为 -兼容性别名,但新的文档/配置示例应使用 `openai/gpt-*`。 +旧版 `openai-codex/gpt-*` 和 `codex/gpt-*` 引用仍然作为兼容别名被接受,但新的文档和配置示例应使用 `openai/gpt-*`。 -Harness 选择不是一个实时会话控制项。当一个嵌入式轮次运行时, -OpenClaw 会在该会话上记录所选 harness id,并继续在同一会话 id 的后续轮次中使用它。若你希望未来会话改用其他 harness,请更改 `embeddedHarness` 配置或 -`OPENCLAW_AGENT_RUNTIME`;在已有会话于 PI 和 Codex 之间切换之前, -请使用 `/new` 或 `/reset` 启动一个全新会话。这可以避免将同一份转录 -重放到两个彼此不兼容的原生会话系统中。 +使用 `/status` 确认当前会话实际使用的测试框架。如果选择结果令人意外,请为 `agents/harness` 子系统启用调试日志,并检查 Gateway 网关中的结构化 `agent harness selected` 记录。它包含所选测试框架 id、选择原因、运行时/回退策略,以及在 `auto` 模式下每个插件候选项的支持结果。 -在引入 harness pin 之前创建的旧会话,一旦拥有转录历史,就会被视为 -固定到 PI。更改配置后,请使用 `/new` 或 `/reset`,将该会话显式切换到 -Codex。 +测试框架选择不是实时会话控制。当嵌入式回合运行时,OpenClaw 会将选中的测试框架 id 记录到该会话上,并在同一会话 id 的后续回合中继续使用它。当你希望未来的新会话使用另一种测试框架时,请更改 `embeddedHarness` 配置或 `OPENCLAW_AGENT_RUNTIME`;如果要在现有对话中在 Pi 和 Codex 之间切换,请先使用 `/new` 或 `/reset` 启动一个新会话。这样可以避免用两套不兼容的原生会话系统重放同一份转录记录。 -`/status` 会在 `Fast` 旁显示生效的非 PI harness,例如 -`Fast · codex`。默认的 PI harness 仍显示为 `Runner: pi (embedded)`,并且不会 -额外显示单独的 harness 徽章。 +在引入测试框架固定机制之前创建的旧会话,一旦已有转录历史,就会被视为固定到 Pi。更改配置后,请使用 `/new` 或 `/reset`,让该对话改为使用 Codex。 + +`/status` 会在 `Fast` 旁边显示当前实际使用的非 Pi 测试框架,例如 `Fast · codex`。默认的 Pi 测试框架仍显示为 `Runner: pi (embedded)`,不会额外显示单独的测试框架徽标。 ## 要求 -- OpenClaw,且内置 `codex` 插件可用。 -- Codex app-server `0.118.0` 或更高版本。 -- app-server 进程可使用的 Codex 认证。 +- OpenClaw,且可用内置的 `codex` 插件。 +- Codex 应用服务器 `0.118.0` 或更高版本。 +- 应用服务器进程可用的 Codex 认证信息。 -该插件会阻止旧版或未带版本号的 app-server 握手。这可以确保 -OpenClaw 只运行在已测试过的协议表面上。 +该插件会阻止较旧或没有版本信息的应用服务器握手。这可确保 OpenClaw 始终使用其已测试过的协议接口。 -对于 live 和 Docker smoke 测试,认证通常来自 `OPENAI_API_KEY`,以及 -可选的 Codex CLI 文件,例如 `~/.codex/auth.json` 和 -`~/.codex/config.toml`。请使用与你本地 Codex app-server -相同的认证材料。 +对于实时和 Docker 冒烟测试,认证信息通常来自 `OPENAI_API_KEY`,以及可选的 Codex CLI 文件,如 `~/.codex/auth.json` 和 `~/.codex/config.toml`。请使用与你本地 Codex 应用服务器相同的认证材料。 ## 最小配置 -使用 `openai/gpt-5.5`,启用内置插件,并强制使用 `codex` harness: +使用 `openai/gpt-5.5`,启用内置插件,并强制使用 `codex` 测试框架: ```json5 { @@ -106,7 +85,7 @@ OpenClaw 只运行在已测试过的协议表面上。 } ``` -如果你的配置使用 `plugins.allow`,也请将 `codex` 包含进去: +如果你的配置使用了 `plugins.allow`,也请将 `codex` 包含进去: ```json5 { @@ -121,14 +100,11 @@ OpenClaw 只运行在已测试过的协议表面上。 } ``` -旧配置如果将 `agents.defaults.model` 或某个智能体模型设置为 -`codex/`,仍会自动启用内置 `codex` 插件。新配置应优先使用 -`openai/`,并搭配上面的显式 `embeddedHarness` 条目。 +如果旧版配置将 `agents.defaults.model` 或某个智能体模型设置为 `codex/`,仍会自动启用内置的 `codex` 插件。新配置应优先使用 `openai/`,并配合上面显式的 `embeddedHarness` 配置项。 -## 添加 Codex 而不替换其他模型 +## 在不替换其他模型的情况下添加 Codex -当你希望旧版 `codex/*` 引用选择 Codex,而其他所有情况仍使用 -PI 时,请保持 `runtime: "auto"`。对于新配置,建议在需要使用该 harness 的智能体上显式设置 `runtime: "codex"`。 +如果你希望旧版 `codex/*` 引用选择 Codex,而其他所有内容继续使用 Pi,请保持 `runtime: "auto"`。对于新配置,建议仅在应使用该测试框架的智能体上显式设置 `runtime: "codex"`。 ```json5 { @@ -158,16 +134,15 @@ PI 时,请保持 `runtime: "auto"`。对于新配置,建议在需要使用 } ``` -采用这种形状时: +在这种结构下: -- `/model gpt` 或 `/model openai/gpt-5.5` 会为该配置使用 Codex app-server harness。 -- `/model opus` 会使用 Anthropic 提供商路径。 -- 如果选择了非 Codex 模型,PI 仍然作为兼容性 harness 保留。 +- `/model gpt` 或 `/model openai/gpt-5.5` 会在此配置中使用 Codex 应用服务器测试框架。 +- `/model opus` 使用 Anthropic 提供商路径。 +- 如果选择的是非 Codex 模型,Pi 仍然是兼容性测试框架。 -## 仅 Codex 部署 +## 仅使用 Codex 的部署 -当你需要证明每一个嵌入式智能体轮次都使用 -Codex harness 时,请禁用 PI 回退: +当你需要证明每一个嵌入式智能体回合都使用 Codex 测试框架时,请禁用 Pi 回退: ```json5 { @@ -183,7 +158,7 @@ Codex harness 时,请禁用 PI 回退: } ``` -环境变量覆盖: +环境覆盖: ```bash OPENCLAW_AGENT_RUNTIME=codex \ @@ -191,13 +166,11 @@ OPENCLAW_AGENT_HARNESS_FALLBACK=none \ openclaw gateway run ``` -禁用回退后,如果 Codex 插件被禁用、 -app-server 版本过旧,或 app-server 无法启动,OpenClaw 会快速失败。 +禁用回退后,如果 Codex 插件被禁用、应用服务器版本过旧,或者应用服务器无法启动,OpenClaw 会尽早失败。 -## 按智能体使用 Codex +## 按智能体启用 Codex -你可以让某个智能体仅使用 Codex,而默认智能体保持正常的 -自动选择: +你可以让某个智能体仅使用 Codex,而默认智能体保持普通的自动选择: ```json5 { @@ -228,15 +201,11 @@ app-server 版本过旧,或 app-server 无法启动,OpenClaw 会快速失败 } ``` -使用常规会话命令切换智能体和模型。`/new` 会创建一个全新的 -OpenClaw 会话,而 Codex harness 会按需创建或恢复其侧车 app-server -线程。`/reset` 会清除该线程的 OpenClaw 会话绑定, -并让下一轮再次根据当前配置解析 harness。 +使用常规会话命令切换智能体和模型。`/new` 会创建一个新的 OpenClaw 会话,而 Codex 测试框架会按需创建或恢复它的 sidecar 应用服务器线程。`/reset` 会清除该线程的 OpenClaw 会话绑定,并让下一回合重新根据当前配置解析测试框架。 ## 模型发现 -默认情况下,Codex 插件会向 app-server 请求可用模型。如果 -发现失败或超时,它会使用内置的回退目录,其中包括: +默认情况下,Codex 插件会向应用服务器请求可用模型。如果发现失败或超时,它会使用内置的回退目录,包含: - GPT-5.5 - GPT-5.4 mini @@ -262,8 +231,7 @@ OpenClaw 会话,而 Codex harness 会按需创建或恢复其侧车 app-server } ``` -如果你希望启动时避免探测 Codex,并固定使用回退目录, -请禁用发现: +如果你希望启动时避免探测 Codex,并始终使用回退目录,请禁用发现: ```json5 { @@ -282,22 +250,17 @@ OpenClaw 会话,而 Codex harness 会按需创建或恢复其侧车 app-server } ``` -## App-server 连接与策略 +## 应用服务器连接与策略 -默认情况下,插件会使用以下命令在本地启动 Codex: +默认情况下,插件会在本地通过以下命令启动 Codex: ```bash codex app-server --listen stdio:// ``` -默认情况下,OpenClaw 会以 YOLO 模式启动本地 Codex harness 会话: -`approvalPolicy: "never"`、`approvalsReviewer: "user"`,以及 -`sandbox: "danger-full-access"`。这是用于 -自治 heartbeat 的受信任本地运维姿态:Codex 可以使用 shell 和网络工具,而不会 -停在无人响应的原生审批提示上。 +默认情况下,OpenClaw 会以 YOLO 模式启动本地 Codex 测试框架会话:`approvalPolicy: "never"`、`approvalsReviewer: "user"` 和 `sandbox: "danger-full-access"`。这是用于自主心跳的受信任本地操作员姿态:Codex 可以使用 shell 和网络工具,而不会停在无人响应的原生审批提示上。 -若要启用 Codex guardian 审查式审批,请设置 `appServer.mode: -"guardian"`: +如果你想启用由 Codex guardian 审核的审批,请设置 `appServer.mode: "guardian"`: ```json5 { @@ -317,11 +280,11 @@ codex app-server --listen stdio:// } ``` -Guardian 是原生 Codex 审批审查者。当 Codex 请求离开沙箱、写入工作区之外的内容,或添加像网络访问这样的权限时,Codex 会将该审批请求路由给一个 reviewer subagent,而不是弹出人工提示。该 reviewer 会应用 Codex 的风险框架,并批准或拒绝具体请求。当你希望比 YOLO 模式拥有更多护栏,但仍需要无人值守智能体持续推进时,请使用 Guardian。 +Guardian 是 Codex 的原生审批审核器。当 Codex 请求离开沙箱、在工作区外写入,或添加诸如网络访问之类的权限时,Codex 会将该审批请求路由给一个 reviewer 子智能体,而不是弹出人工提示。该 reviewer 会应用 Codex 的风险框架,并批准或拒绝该具体请求。如果你希望比 YOLO 模式有更多保护措施,但仍需要无人值守的智能体继续推进任务,请使用 Guardian。 -`guardian` 预设会展开为 `approvalPolicy: "on-request"`、`approvalsReviewer: "guardian_subagent"` 和 `sandbox: "workspace-write"`。单独的策略字段仍会覆盖 `mode`,因此高级部署可以将该预设与显式选择混合使用。 +`guardian` 预设会展开为 `approvalPolicy: "on-request"`、`approvalsReviewer: "guardian_subagent"` 和 `sandbox: "workspace-write"`。各个单独的策略字段仍然会覆盖 `mode`,因此高级部署可以将该预设与显式设置混合使用。 -对于已在运行的 app-server,请使用 WebSocket 传输: +对于已经在运行的应用服务器,请使用 WebSocket 传输: ```json5 { @@ -348,19 +311,19 @@ Guardian 是原生 Codex 审批审查者。当 Codex 请求离开沙箱、写入 | 字段 | 默认值 | 含义 | | ------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------- | | `transport` | `"stdio"` | `"stdio"` 会启动 Codex;`"websocket"` 会连接到 `url`。 | -| `command` | `"codex"` | stdio 传输所使用的可执行文件。 | -| `args` | `["app-server", "--listen", "stdio://"]` | stdio 传输所使用的参数。 | -| `url` | 未设置 | WebSocket app-server URL。 | -| `authToken` | 未设置 | WebSocket 传输的 Bearer token。 | -| `headers` | `{}` | 额外的 WebSocket headers。 | -| `requestTimeoutMs` | `60000` | app-server 控制平面调用的超时时间。 | -| `mode` | `"yolo"` | YOLO 或 guardian 审查执行的预设。 | -| `approvalPolicy` | `"never"` | 发送到线程启动/恢复/轮次的原生 Codex 审批策略。 | +| `command` | `"codex"` | 用于 stdio 传输的可执行文件。 | +| `args` | `["app-server", "--listen", "stdio://"]` | 用于 stdio 传输的参数。 | +| `url` | 未设置 | WebSocket 应用服务器 URL。 | +| `authToken` | 未设置 | 用于 WebSocket 传输的 Bearer token。 | +| `headers` | `{}` | 额外的 WebSocket 标头。 | +| `requestTimeoutMs` | `60000` | 应用服务器控制平面调用的超时时间。 | +| `mode` | `"yolo"` | 用于 YOLO 或 guardian 审核执行的预设。 | +| `approvalPolicy` | `"never"` | 发送到线程启动/恢复/回合的原生 Codex 审批策略。 | | `sandbox` | `"danger-full-access"` | 发送到线程启动/恢复的原生 Codex 沙箱模式。 | -| `approvalsReviewer` | `"user"` | 使用 `"guardian_subagent"` 可让 Codex Guardian 审查提示。 | -| `serviceTier` | 未设置 | 可选的 Codex app-server 服务层级:`"fast"`、`"flex"` 或 `null`。无效的旧版值会被忽略。 +| `approvalsReviewer` | `"user"` | 使用 `"guardian_subagent"` 让 Codex Guardian 审核提示。 | +| `serviceTier` | 未设置 | 可选的 Codex 应用服务器服务层级:`"fast"`、`"flex"` 或 `null`。无效的旧值会被忽略。 | -较旧的环境变量在匹配的配置字段未设置时,仍可作为本地测试的回退方式: +当对应配置字段未设置时,较旧的环境变量仍可作为本地测试的回退方式继续使用: - `OPENCLAW_CODEX_APP_SERVER_BIN` - `OPENCLAW_CODEX_APP_SERVER_ARGS` @@ -368,10 +331,7 @@ Guardian 是原生 Codex 审批审查者。当 Codex 请求离开沙箱、写入 - `OPENCLAW_CODEX_APP_SERVER_APPROVAL_POLICY` - `OPENCLAW_CODEX_APP_SERVER_SANDBOX` -`OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1` 已被移除。请改用 -`plugins.entries.codex.config.appServer.mode: "guardian"`,或者在一次性本地测试中使用 -`OPENCLAW_CODEX_APP_SERVER_MODE=guardian`。对于可重复部署,优先使用配置, -因为这样可以将插件行为与 Codex harness 其余设置一起放在同一个已审查文件中。 +`OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1` 已被移除。请改用 `plugins.entries.codex.config.appServer.mode: "guardian"`,或者在一次性本地测试中使用 `OPENCLAW_CODEX_APP_SERVER_MODE=guardian`。对于可重复部署,优先使用配置,因为这样可以将插件行为与 Codex 测试框架其余设置保存在同一个经过审查的文件中。 ## 常见配方 @@ -389,7 +349,7 @@ Guardian 是原生 Codex 审批审查者。当 Codex 请求离开沙箱、写入 } ``` -仅验证 Codex harness,并禁用 PI 回退: +仅使用 Codex 的测试框架验证,并禁用 Pi 回退: ```json5 { @@ -406,7 +366,7 @@ Guardian 是原生 Codex 审批审查者。当 Codex 请求离开沙箱、写入 } ``` -Guardian 审查式 Codex 审批: +由 Guardian 审核的 Codex 审批: ```json5 { @@ -428,7 +388,7 @@ Guardian 审查式 Codex 审批: } ``` -使用显式 headers 的远程 app-server: +带显式标头的远程应用服务器: ```json5 { @@ -451,83 +411,57 @@ Guardian 审查式 Codex 审批: } ``` -模型切换仍由 OpenClaw 控制。当一个 OpenClaw 会话附加到已有 -Codex 线程时,下一轮会再次将当前选中的 -OpenAI 模型、提供商、审批策略、沙箱和服务层级发送给 -app-server。将 `openai/gpt-5.5` 切换为 `openai/gpt-5.2` 时,会保留 -线程绑定,但会要求 Codex 使用新选中的模型继续运行。 +模型切换仍由 OpenClaw 控制。当 OpenClaw 会话附加到现有 Codex 线程时,下一回合会再次将当前选中的 OpenAI 模型、provider、审批策略、沙箱和服务层级发送给应用服务器。从 `openai/gpt-5.5` 切换到 `openai/gpt-5.2` 会保留线程绑定,但会要求 Codex 使用新选中的模型继续执行。 ## Codex 命令 -内置插件将 `/codex` 注册为授权的斜杠命令。它是通用的,适用于任何支持 OpenClaw 文本命令的渠道。 +内置插件将 `/codex` 注册为已授权的斜杠命令。它是通用命令,可用于任何支持 OpenClaw 文本命令的渠道。 常见形式: -- `/codex status` 显示实时 app-server 连接性、模型、账户、速率限制、MCP 服务器和 skills。 -- `/codex models` 列出实时 Codex app-server 模型。 +- `/codex status` 显示实时的应用服务器连接状态、模型、账户、速率限制、MCP 服务器和技能。 +- `/codex models` 列出实时的 Codex 应用服务器模型。 - `/codex threads [filter]` 列出最近的 Codex 线程。 - `/codex resume ` 将当前 OpenClaw 会话附加到现有 Codex 线程。 -- `/codex compact` 请求 Codex app-server 对附加线程执行压缩总结。 -- `/codex review` 为附加线程启动 Codex 原生审查。 +- `/codex compact` 请求 Codex 应用服务器压缩当前附加的线程。 +- `/codex review` 为当前附加的线程启动 Codex 原生审查。 - `/codex account` 显示账户和速率限制状态。 -- `/codex mcp` 列出 Codex app-server MCP 服务器状态。 -- `/codex skills` 列出 Codex app-server Skills。 +- `/codex mcp` 列出 Codex 应用服务器 MCP 服务器状态。 +- `/codex skills` 列出 Codex 应用服务器 Skills。 -`/codex resume` 会写入与 harness 正常轮次所使用的相同侧车绑定文件。下一条消息到来时,OpenClaw 会恢复该 Codex 线程,将当前选中的 OpenClaw `codex/*` 模型传入 app-server,并保持扩展历史启用。 +`/codex resume` 会写入与测试框架在正常回合中使用的同一个 sidecar 绑定文件。在下一条消息时,OpenClaw 会恢复该 Codex 线程,将当前选中的 OpenClaw 模型传入应用服务器,并保持启用扩展历史记录。 -该命令表面要求 Codex app-server 版本为 `0.118.0` 或更新。若未来版本或自定义 app-server 未暴露某个 JSON-RPC 方法,单个控制方法会报告为 `unsupported by this Codex app-server`。 +该命令界面要求 Codex 应用服务器版本为 `0.118.0` 或更高。如果未来版本或自定义应用服务器未公开某个 JSON-RPC 方法,则对应的单个控制方法会显示为 `unsupported by this Codex app-server`。 -## 工具、媒体与压缩总结 +## 工具、媒体和压缩 -Codex harness 只改变底层嵌入式智能体执行器。 +Codex 测试框架只会更改底层嵌入式智能体执行器。 -OpenClaw 仍然构建工具列表,并从 -harness 接收动态工具结果。文本、图像、视频、音乐、TTS、审批以及消息工具输出 -仍然通过正常的 OpenClaw 传递路径流动。 +OpenClaw 仍然负责构建工具列表,并从测试框架接收动态工具结果。文本、图像、视频、音乐、TTS、审批以及消息工具输出,都会继续通过正常的 OpenClaw 传输路径处理。 -当 Codex 将 `_meta.codex_approval_kind` 标记为 -`"mcp_tool_call"` 时,Codex MCP 工具审批请求会通过 OpenClaw 的插件审批流程进行路由;其他请求获取输入的情形以及自由格式输入请求仍然会失败即关闭。 +当 Codex 将 `_meta.codex_approval_kind` 标记为 `"mcp_tool_call"` 时,Codex MCP 工具审批引导会通过 OpenClaw 的插件审批流程进行路由;其他引导请求和自由形式输入请求仍会默认拒绝。 -当所选模型使用 Codex harness 时,原生线程压缩总结会委托给 -Codex app-server。OpenClaw 会保留转录镜像,用于渠道历史、 -搜索、`/new`、`/reset`,以及未来的模型或 harness 切换。该 -镜像包括用户提示词、最终助手文本,以及在 app-server 发出时的轻量级 Codex -推理或计划记录。目前,OpenClaw 只记录原生压缩总结开始与完成信号。它尚未暴露 -人类可读的压缩总结摘要,也未提供可审计的列表来说明 Codex -在压缩总结后保留了哪些条目。 +当选中的模型使用 Codex 测试框架时,原生线程压缩会委托给 Codex 应用服务器。OpenClaw 会继续保留一个转录镜像,用于渠道历史记录、搜索、`/new`、`/reset` 以及未来的模型或测试框架切换。该镜像包括用户提示、最终助手文本,以及应用服务器发出时的轻量级 Codex 推理或计划记录。目前,OpenClaw 只记录原生压缩的开始和完成信号。它尚未公开可供人类阅读的压缩摘要,也无法提供 Codex 在压缩后保留了哪些条目的可审计列表。 -媒体生成不需要 PI。图像、视频、音乐、PDF、TTS 以及媒体 -理解仍然继续使用匹配的提供商/模型设置,例如 -`agents.defaults.imageGenerationModel`、`videoGenerationModel`、`pdfModel` 和 -`messages.tts`。 +媒体生成功能不依赖 Pi。图像、视频、音乐、PDF、TTS 和媒体理解仍会继续使用对应的 provider/模型设置,例如 `agents.defaults.imageGenerationModel`、`videoGenerationModel`、`pdfModel` 和 `messages.tts`。 ## 故障排除 -**`/model` 中看不到 Codex:** 启用 `plugins.entries.codex.enabled`, -设置一个 `codex/*` 模型引用,或检查 `plugins.allow` 是否排除了 `codex`。 +**`/model` 中看不到 Codex:** 启用 `plugins.entries.codex.enabled`,选择带有 `embeddedHarness.runtime: "codex"` 的 `openai/gpt-*` 模型(或旧版 `codex/*` 引用),并检查 `plugins.allow` 是否排除了 `codex`。 -**OpenClaw 使用了 PI 而不是 Codex:** 如果没有 Codex harness 接管该运行, -OpenClaw 可能会使用 PI 作为兼容性后端。测试时请设置 -`embeddedHarness.runtime: "codex"` 以强制选择 Codex,或设置 -`embeddedHarness.fallback: "none"`,使得当没有匹配的插件 harness 时直接失败。一旦 -Codex app-server 被选中,其失败会直接暴露出来,而无需额外的 -回退配置。 +**OpenClaw 使用 Pi 而不是 Codex:** 如果没有任何 Codex 测试框架声明处理该运行,OpenClaw 可能会使用 Pi 作为兼容后端。测试时请设置 `embeddedHarness.runtime: "codex"` 以强制选择 Codex,或设置 `embeddedHarness.fallback: "none"`,以便在没有匹配的插件测试框架时报错。一旦选择了 Codex 应用服务器,其失败会直接暴露出来,不需要额外的回退配置。 -**app-server 被拒绝:** 升级 Codex,确保 app-server 握手 -报告版本为 `0.118.0` 或更新。 +**应用服务器被拒绝:** 升级 Codex,使应用服务器握手报告的版本为 `0.118.0` 或更高。 -**模型发现很慢:** 调低 `plugins.entries.codex.config.discovery.timeoutMs` -或禁用发现。 +**模型发现过慢:** 降低 `plugins.entries.codex.config.discovery.timeoutMs` 或禁用发现。 -**WebSocket 传输立即失败:** 检查 `appServer.url`、`authToken`, -以及远程 app-server 是否使用相同版本的 Codex app-server 协议。 +**WebSocket 传输立即失败:** 检查 `appServer.url`、`authToken`,以及远程应用服务器是否使用相同版本的 Codex 应用服务器协议。 -**非 Codex 模型使用了 PI:** 这是预期行为。Codex harness 只会接管 -`codex/*` 模型引用。 +**非 Codex 模型使用了 Pi:** 这是预期行为,除非你强制设置了 `embeddedHarness.runtime: "codex"`(或选择了旧版 `codex/*` 引用)。普通的 `openai/gpt-*` 和其他 provider 引用都会继续使用其正常的 provider 路径。 ## 相关内容 -- [智能体 Harness 插件](/zh-CN/plugins/sdk-agent-harness) +- [智能体测试框架插件](/zh-CN/plugins/sdk-agent-harness) - [模型提供商](/zh-CN/concepts/model-providers) - [配置参考](/zh-CN/gateway/configuration-reference) - [测试](/zh-CN/help/testing#live-codex-app-server-harness-smoke) diff --git a/docs/zh-CN/plugins/sdk-agent-harness.md b/docs/zh-CN/plugins/sdk-agent-harness.md index f67394d16..fa995c6ab 100644 --- a/docs/zh-CN/plugins/sdk-agent-harness.md +++ b/docs/zh-CN/plugins/sdk-agent-harness.md @@ -1,55 +1,49 @@ --- read_when: - - 你正在更改内嵌智能体运行时或 harness 注册表 + - 你正在更改嵌入式智能体运行时或 harness 注册表 - 你正在从内置或受信任插件注册一个智能体 harness - 你需要了解 Codex 插件与模型提供商之间的关系 sidebarTitle: Agent Harness -summary: 供替换底层内嵌智能体执行器的插件使用的实验性 SDK 接口 +summary: 用于替换底层嵌入式智能体执行器的插件实验性 SDK 接口 title: 智能体 harness 插件 x-i18n: - generated_at: "2026-04-23T20:57:19Z" + generated_at: "2026-04-23T21:49:30Z" model: gpt-5.4 provider: openai - source_hash: 69d0c4febbc0f0397d4fc8a212039a2d78764798b82f48e600daf68626826904 + source_hash: 966d685627b11651fbd0c7fe00a7e3e412c14b39511845ecfcdc4366fa9f8767 source_path: plugins/sdk-agent-harness.md workflow: 15 --- -一个**智能体 harness** 是执行一次已准备好的 OpenClaw 智能体轮次的底层执行器。 -它不是模型提供商,不是渠道,也不是工具注册表。 +**智能体 harness** 是为一个已准备好的 OpenClaw 智能体轮次提供的底层执行器。它不是模型提供商,不是渠道,也不是工具注册表。 -仅应将这个接口用于内置或受信任的原生插件。该合约 -仍然是实验性的,因为其参数类型有意镜像当前的 -内嵌执行器。 +仅对内置或受信任的原生插件使用此接口。该契约仍然是实验性的,因为参数类型有意映射当前的嵌入式运行器。 ## 何时使用 harness -当某个模型家族拥有自己的原生会话 -运行时,而普通的 OpenClaw 提供商传输抽象并不合适时,请注册一个智能体 harness。 +当某个模型家族拥有自己的原生会话运行时,而常规的 OpenClaw 提供商传输层并不是合适抽象时,请注册一个智能体 harness。 示例: -- 拥有线程和压缩逻辑的原生编码智能体服务器 -- 必须流式传输原生计划/推理/工具事件的本地 CLI 或 daemon -- 除 OpenClaw 会话转录外,还需要自身 resume id 的模型运行时 +- 拥有线程与压缩能力的原生编码智能体服务器 +- 必须流式传输原生计划/推理/工具事件的本地 CLI 或守护进程 +- 除了 OpenClaw 会话 transcript 之外,还需要自己的 resume id 的模型运行时 -不要仅仅为了增加一个新的 LLM API 就注册 harness。对于普通的 HTTP 或 -WebSocket 模型 API,请构建一个[提供商插件](/zh-CN/plugins/sdk-provider-plugins)。 +**不要** 仅仅为了添加一个新的 LLM API 而注册 harness。对于常规的 HTTP 或 WebSocket 模型 API,请构建一个[提供商插件](/zh-CN/plugins/sdk-provider-plugins)。 -## 核心仍然负责什么 +## 核心仍负责的内容 -在选择 harness 之前,OpenClaw 已经解析好了: +在选择 harness 之前,OpenClaw 已经解析了: -- 提供商和模型 -- 运行时身份验证状态 -- thinking 级别和上下文预算 -- OpenClaw 转录/会话文件 +- provider 和 model +- 运行时认证状态 +- 思考级别和上下文预算 +- OpenClaw transcript/会话文件 - 工作区、沙箱和工具策略 -- 渠道回复回调和流式回调 +- 渠道回复回调和流式传输回调 - 模型回退和实时模型切换策略 -这种拆分是有意设计的。Harness 负责运行一次已准备好的尝试;它不会选择 -提供商、替代渠道投递,或静默切换模型。 +这种拆分是有意设计的。harness 负责运行一个已准备好的尝试;它不会选择提供商、替换渠道投递,也不会静默切换模型。 ## 注册 harness @@ -70,9 +64,9 @@ const myHarness: AgentHarness = { }, async runAttempt(params) { - // 启动或恢复你的原生线程。 - // 使用 params.prompt、params.tools、params.images、params.onPartialReply、 - // params.onAgentEvent,以及其他已准备好的尝试字段。 + // Start or resume your native thread. + // Use params.prompt, params.tools, params.images, params.onPartialReply, + // params.onAgentEvent, and the other prepared attempt fields. return await runMyNativeTurn(params); }, }; @@ -89,91 +83,55 @@ export default definePluginEntry({ ## 选择策略 -OpenClaw 会在提供商/模型解析之后选择 harness: +OpenClaw 会在 provider/model 解析之后选择一个 harness: -1. 现有会话中记录的 harness id 优先生效,因此配置/环境变量更改不会 - 热切换该转录到另一个运行时。 -2. `OPENCLAW_AGENT_RUNTIME=` 会为尚未固定的会话强制选择该 id 对应的已注册 harness。 -3. `OPENCLAW_AGENT_RUNTIME=pi` 会强制使用内置 PI harness。 -4. `OPENCLAW_AGENT_RUNTIME=auto` 会让已注册 harness 询问自己是否支持 - 当前解析出的提供商/模型。 -5. 如果没有任何已注册 harness 匹配,则 OpenClaw 使用 PI,除非 - PI 回退已被禁用。 +1. 已有会话中记录的 harness id 优先生效,因此配置/环境变量的变化不会将该 transcript 热切换到另一个运行时。 +2. `OPENCLAW_AGENT_RUNTIME=` 会为尚未固定的会话强制使用具有该 id 的已注册 harness。 +3. `OPENCLAW_AGENT_RUNTIME=pi` 会强制使用内置的 PI harness。 +4. `OPENCLAW_AGENT_RUNTIME=auto` 会让已注册的 harness 判断它们是否支持已解析的 provider/model。 +5. 如果没有匹配的已注册 harness,OpenClaw 会使用 PI,除非已禁用 PI 回退。 -插件 harness 失败会表现为运行失败。在 `auto` 模式下,只有在没有任何已注册插件 harness 支持当前解析出的 -提供商/模型时,才会使用 PI 回退。一旦某个插件 harness 已经声明接管该次运行,OpenClaw 就不会再通过 PI 重新回放同一轮,因为这可能改变身份验证/运行时语义 -或导致副作用重复。 +插件 harness 失败会以运行失败的形式呈现。在 `auto` 模式下,只有当没有已注册的插件 harness 支持已解析的 provider/model 时,才会使用 PI 回退。一旦某个插件 harness 已经接管一次运行,OpenClaw 就不会再通过 PI 重放同一轮次,因为这可能改变认证/运行时语义或造成副作用重复。 -选定的 harness id 会在一次内嵌运行后与会话 id 一起持久化。 -在引入 harness 固定前创建的旧会话,一旦有转录历史,就会被视为固定到 PI。 -在 PI 和原生插件 harness 之间切换时,请使用一个新的/已重置的会话。 -`/status` 会在 `Fast` 旁边显示诸如 `codex` -这样的非默认 harness id;PI 会被隐藏,因为它是默认兼容路径。 +在一次嵌入式运行之后,所选的 harness id 会与 session id 一起持久化。对于在 harness 固定机制出现之前创建的旧会话,一旦其拥有 transcript 历史,就会被视为固定到 PI。要在 PI 与原生插件 harness 之间切换,请使用新的/已重置的会话。`/status` 会在 `Fast` 旁边显示诸如 `codex` 这样的非默认 harness id;由于 PI 是默认兼容路径,因此会被隐藏。如果所选 harness 出乎你的预期,请启用 `agents/harness` 调试日志,并检查 Gateway 网关中的结构化 `agent harness selected` 记录。其中包含所选 harness id、选择原因、运行时/回退策略,以及在 `auto` 模式下各插件候选项的支持结果。 -内置 Codex 插件将 `codex` 注册为它的 harness id。核心将其视为普通插件 harness id; -Codex 特定别名应归属于插件或运维配置,而不是共享运行时选择器。 +内置的 Codex 插件将 `codex` 注册为其 harness id。核心将其视为普通的插件 harness id;Codex 专用别名应放在插件或运维配置中,而不是共享运行时选择器中。 -## 提供商与 harness 的配对 +## provider 与 harness 配对 -大多数 harness 也应同时注册一个提供商。提供商会让模型引用、 -身份验证状态、模型元数据以及 `/model` 选择对 OpenClaw 的其他部分可见。 -然后 harness 在 `supports(...)` 中声明自己接管该提供商。 +大多数 harness 也应该注册一个 provider。provider 会让模型引用、认证状态、模型元数据和 `/model` 选择对 OpenClaw 的其他部分可见。随后,harness 会在 `supports(...)` 中声明接管该 provider。 -内置 Codex 插件采用了这种模式: +内置的 Codex 插件遵循这一模式: - provider id:`codex` -- 用户模型引用:规范形式为 `openai/gpt-5.5`,并配合 - `embeddedHarness.runtime: "codex"`;旧版 `codex/gpt-*` 引用仍然为了兼容而被接受 +- 用户模型引用:规范形式为 `openai/gpt-5.5` 加上 `embeddedHarness.runtime: "codex"`;旧版 `codex/gpt-*` 引用仍为兼容性而继续接受 - harness id:`codex` -- 身份验证:合成的提供商可用性,因为 Codex harness 拥有原生 Codex 登录/会话 -- app-server 请求:OpenClaw 向 Codex 发送裸模型 id,并让 - harness 与原生 app-server 协议通信 +- 认证:合成的 provider 可用性,因为 Codex harness 负责原生 Codex 登录/会话 +- app-server 请求:OpenClaw 会将裸模型 id 发送给 Codex,并让 harness 与原生 app-server 协议通信 -Codex 插件是增量式的。普通的 `openai/gpt-*` 引用仍然走 -标准 OpenClaw 提供商路径,除非你通过 -`embeddedHarness.runtime: "codex"` 强制使用 Codex harness。旧版 `codex/gpt-*` 引用 -仍然会为了兼容而选择 Codex 提供商和 harness。 +Codex 插件是增量式的。普通的 `openai/gpt-*` 引用仍会使用常规的 OpenClaw provider 路径,除非你通过 `embeddedHarness.runtime: "codex"` 强制使用 Codex harness。较旧的 `codex/gpt-*` 引用仍会为兼容性而选择 Codex provider 和 harness。 -关于运维设置、模型前缀示例和仅 Codex 配置,请参见 -[Codex Harness](/zh-CN/plugins/codex-harness)。 +有关运维设置、模型前缀示例和仅限 Codex 的配置,请参阅 [Codex Harness](/zh-CN/plugins/codex-harness)。 -OpenClaw 要求 Codex app-server 版本为 `0.118.0` 或更高。Codex 插件会检查 -app-server 初始化握手,并阻止较旧或未标明版本的服务器, -以确保 OpenClaw 仅在其已测试过的协议接口上运行。 +OpenClaw 要求 Codex app-server 为 `0.118.0` 或更新版本。Codex 插件会检查 app-server 初始化握手,并阻止较旧或未标注版本的服务器,以确保 OpenClaw 仅在其已测试过的协议接口上运行。 -### Codex app-server 工具结果中间件 +### Codex app-server tool-result 中间件 -当其 manifest 声明 `contracts.embeddedExtensionFactories: ["codex-app-server"]` 时, -内置插件还可以通过 `api.registerCodexAppServerExtensionFactory(...)` 挂接 Codex app-server 特定的 `tool_result` -中间件。 -这是受信任插件的扩展点,用于在原生 Codex harness 内部运行异步工具结果转换,然后再将工具输出映射回 OpenClaw 转录。 +当插件清单声明 `contracts.embeddedExtensionFactories: ["codex-app-server"]` 时,内置插件还可以通过 `api.registerCodexAppServerExtensionFactory(...)` 挂载特定于 Codex app-server 的 `tool_result` 中间件。这是一个受信任插件的扩展点,适用于那些需要在原生 Codex harness 内部运行的异步工具结果转换,然后再将工具输出投射回 OpenClaw transcript。 ### 原生 Codex harness 模式 -内置的 `codex` harness 是内嵌 OpenClaw -智能体轮次的原生 Codex 模式。请先启用内置 `codex` 插件,并且如果你的配置使用了严格 allowlist,请将 `codex` 加入 -`plugins.allow`。新配置应使用 `openai/gpt-*` 并配合 `embeddedHarness.runtime: "codex"`。旧版 -`openai-codex/*` 和 `codex/*` 模型引用仍保留为兼容别名。 +内置的 `codex` harness 是嵌入式 OpenClaw 智能体轮次的原生 Codex 模式。请先启用内置的 `codex` 插件;如果你的配置使用了严格的 allowlist,还要在 `plugins.allow` 中包含 `codex`。新配置应使用 `openai/gpt-*` 搭配 `embeddedHarness.runtime: "codex"`。旧版 `openai-codex/*` 和 `codex/*` 模型引用仍保留为兼容性别名。 -当该模式运行时,Codex 拥有原生线程 id、恢复行为、 -压缩逻辑和 app-server 执行。OpenClaw 仍负责聊天渠道、 -可见转录镜像、工具策略、审批、媒体投递和会话 -选择。当你需要证明只有 Codex -app-server 路径能够接管该次运行时,请使用 `embeddedHarness.runtime: "codex"` 并配合 -`embeddedHarness.fallback: "none"`。该配置只是一个选择保护: -Codex app-server 失败本来就会直接失败,而不是通过 PI 重试。 +当该模式运行时,Codex 负责原生线程 id、resume 行为、压缩和 app-server 执行。OpenClaw 仍负责聊天渠道、可见 transcript 镜像、工具策略、审批、媒体投递和会话选择。当你需要证明只有 Codex app-server 路径可以接管该运行时,请使用 `embeddedHarness.runtime: "codex"` 搭配 `embeddedHarness.fallback: "none"`。该配置仅是一个选择保护措施:Codex app-server 失败本来就会直接失败,而不会通过 PI 重试。 ## 禁用 PI 回退 -默认情况下,OpenClaw 会以 `agents.defaults.embeddedHarness` -设置为 `{ runtime: "auto", fallback: "pi" }` 来运行内嵌智能体。在 `auto` 模式下,已注册插件 -harness 可以接管某个提供商/模型对。如果没有任何匹配,OpenClaw 会回退到 PI。 +默认情况下,OpenClaw 运行嵌入式智能体时,`agents.defaults.embeddedHarness` 设置为 `{ runtime: "auto", fallback: "pi" }`。在 `auto` 模式下,已注册的插件 harness 可以接管某个 provider/model 组合。如果没有匹配项,OpenClaw 会回退到 PI。 -当你需要在缺少插件 harness 选择时直接失败,而不是改用 PI, -请设置 `fallback: "none"`。已选中的插件 harness 失败本来就会硬失败。 -这不会阻止显式的 `runtime: "pi"` 或 `OPENCLAW_AGENT_RUNTIME=pi`。 +当你需要在缺少插件 harness 选择时直接失败,而不是使用 PI 时,请设置 `fallback: "none"`。已选中的插件 harness 失败本来就会硬失败。这不会阻止显式的 `runtime: "pi"` 或 `OPENCLAW_AGENT_RUNTIME=pi`。 -对于仅 Codex 的内嵌运行: +对于仅使用 Codex 的嵌入式运行: ```json { @@ -189,7 +147,7 @@ harness 可以接管某个提供商/模型对。如果没有任何匹配,OpenC } ``` -如果你希望任何已注册插件 harness 都可以接管匹配模型,但绝不希望 OpenClaw 静默回退到 PI,请保持 `runtime: "auto"` 并禁用回退: +如果你希望任何已注册的插件 harness 都可以接管匹配的模型,但又不希望 OpenClaw 静默回退到 PI,请保留 `runtime: "auto"` 并禁用回退: ```json { @@ -204,7 +162,7 @@ harness 可以接管某个提供商/模型对。如果没有任何匹配,OpenC } ``` -按智能体划分的覆盖使用相同结构: +每个智能体的覆盖项使用相同的结构: ```json { @@ -229,8 +187,7 @@ harness 可以接管某个提供商/模型对。如果没有任何匹配,OpenC } ``` -`OPENCLAW_AGENT_RUNTIME` 仍然会覆盖已配置的运行时。使用 -`OPENCLAW_AGENT_HARNESS_FALLBACK=none` 可从环境变量中禁用 PI 回退。 +`OPENCLAW_AGENT_RUNTIME` 仍会覆盖已配置的运行时。使用 `OPENCLAW_AGENT_HARNESS_FALLBACK=none` 可以通过环境变量禁用 PI 回退。 ```bash OPENCLAW_AGENT_RUNTIME=codex \ @@ -238,49 +195,36 @@ OPENCLAW_AGENT_HARNESS_FALLBACK=none \ openclaw gateway run ``` -禁用回退后,当所请求的 harness 未注册、 -不支持已解析的提供商/模型,或在产生轮次副作用前失败时,会话会提前失败。 -这对于仅 Codex 部署以及必须证明 Codex -app-server 路径确实被使用的在线测试来说,是有意为之的行为。 +禁用回退后,如果请求的 harness 未注册、不支持已解析的 provider/model,或者在产生轮次副作用之前就已失败,则会话会提前失败。对于仅使用 Codex 的部署,以及必须证明 Codex app-server 路径确实在使用中的实时测试,这是有意设计的。 -此设置仅控制内嵌智能体 harness。它不会禁用 -图片、视频、音乐、TTS、PDF 或其他按提供商划分的模型路由。 +此设置仅控制嵌入式智能体 harness。它不会禁用图像、视频、音乐、TTS、PDF 或其他提供商特定的模型路由。 -## 原生会话与转录镜像 +## 原生会话与 transcript 镜像 -Harness 可以保留原生 session id、thread id 或 daemon 侧 resume token。 -请将这种绑定与 OpenClaw 会话显式关联,并持续 -将用户可见的助手/工具输出镜像到 OpenClaw 转录中。 +harness 可能会保留原生 session id、thread id 或守护进程侧的 resume token。请将这种绑定显式地与 OpenClaw 会话关联起来,并继续将用户可见的助手/工具输出镜像到 OpenClaw transcript 中。 -OpenClaw 转录仍然是以下内容的兼容层: +OpenClaw transcript 仍然是以下内容的兼容层: - 渠道可见的会话历史 -- 转录搜索和索引 -- 在后续轮次中切换回内置 PI harness +- transcript 搜索与索引 +- 在后续轮次中切换回内置的 PI harness - 通用的 `/new`、`/reset` 和会话删除行为 -如果你的 harness 存储了一个 sidecar 绑定,请实现 `reset(...)`,这样 OpenClaw -才能在所属 OpenClaw 会话被重置时清除它。 +如果你的 harness 存储了 sidecar 绑定,请实现 `reset(...)`,以便 OpenClaw 在所属 OpenClaw 会话被重置时可以清除它。 ## 工具与媒体结果 -核心会构建 OpenClaw 工具列表,并将其传入已准备好的尝试。 -当 harness 执行动态工具调用时,请通过 -harness 结果结构返回工具结果,而不是自行发送渠道媒体。 +核心会构造 OpenClaw 工具列表,并将其传入已准备好的尝试中。当 harness 执行动态工具调用时,请通过 harness 结果结构返回工具结果,而不是自行发送渠道媒体。 -这样可以让文本、图片、视频、音乐、TTS、审批以及消息工具输出 -与基于 PI 的运行保持相同的投递路径。 +这样可以让文本、图像、视频、音乐、TTS、审批以及消息工具输出,与由 PI 支持的运行使用相同的投递路径。 ## 当前限制 -- 公开导入路径是通用的,但某些尝试/结果类型别名 - 仍然为了兼容而保留 `Pi` 命名。 -- 第三方 harness 安装仍是实验性的。在你确实需要原生会话运行时之前, - 优先使用提供商插件。 -- 支持跨轮次切换 harness。不要在一轮执行过程中,在原生工具、审批、助手文本或消息发送已经开始后 - 再切换 harness。 +- 公共导入路径是通用的,但某些 attempt/result 类型别名仍然保留 `Pi` 命名以维持兼容性。 +- 第三方 harness 安装仍是实验性的。在你确实需要原生会话运行时之前,优先使用提供商插件。 +- 支持跨轮次切换 harness。不要在一个轮次进行到一半时切换 harness,尤其是在原生工具、审批、助手文本或消息发送已经开始之后。 -## 相关 +## 相关内容 - [SDK 概览](/zh-CN/plugins/sdk-overview) - [运行时辅助工具](/zh-CN/plugins/sdk-runtime) diff --git a/docs/zh-CN/providers/openai.md b/docs/zh-CN/providers/openai.md index ddb9f71ce..6c93a1c47 100644 --- a/docs/zh-CN/providers/openai.md +++ b/docs/zh-CN/providers/openai.md @@ -1,59 +1,59 @@ --- read_when: - 你想在 OpenClaw 中使用 OpenAI 模型 - - 你想使用 Codex 订阅认证,而不是 API key + - 你想使用 Codex 订阅身份验证,而不是 API 密钥 - 你需要更严格的 GPT-5 智能体执行行为 -summary: 在 OpenClaw 中通过 API key 或 Codex 订阅使用 OpenAI +summary: 在 OpenClaw 中使用 OpenAI 的 API 密钥或 Codex 订阅 title: OpenAI x-i18n: - generated_at: "2026-04-23T21:01:16Z" + generated_at: "2026-04-23T21:49:31Z" model: gpt-5.4 provider: openai - source_hash: 39f5259ef82bb95bb7a94cf36a33c4a3ea2b9ba06f5355dc7abf256167d7a4b9 + source_hash: 25d8fb540af37366c84380feca3dae43e8b206ff77d6a22af3cdddc1cf0373fc source_path: providers/openai.md workflow: 15 --- -OpenAI 为 GPT 模型提供开发者 API。OpenClaw 在相同的规范 OpenAI 模型引用后支持两种认证路径: +OpenAI 为 GPT 模型提供开发者 API。OpenClaw 在同一套规范的 OpenAI 模型引用后支持两种身份验证路径: -- **API key** —— 直接访问 OpenAI Platform,并按用量计费(`openai/*` 模型) -- **Codex 订阅** —— 使用 ChatGPT/Codex 登录与订阅访问。内部认证/provider id 是 `openai-codex`,但新的模型引用仍应使用 `openai/*`。 +- **API 密钥** — 直接访问 OpenAI Platform,并按使用量计费(`openai/*` 模型) +- **Codex 订阅** — 使用 ChatGPT/Codex 登录并通过订阅访问。内部 auth/provider id 为 `openai-codex`,但新的模型引用仍应使用 `openai/*`。 OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 OAuth。 -## OpenClaw 功能覆盖 +## OpenClaw 功能覆盖范围 | OpenAI 能力 | OpenClaw 界面 | 状态 | | ------------------------- | ----------------------------------------- | ------------------------------------------------------ | -| Chat / Responses | `openai/` 模型提供商 | 支持 | -| Codex 订阅模型 | 带 `openai-codex` 认证的 `openai/` | 支持 | -| 服务器端 web 搜索 | 原生 OpenAI Responses 工具 | 支持,当启用 web 搜索且未固定 provider 时 | -| 图像 | `image_generate` | 支持 | -| 视频 | `video_generate` | 支持 | -| 文本转语音 | `messages.tts.provider: "openai"` / `tts` | 支持 | -| 批量语音转文本 | `tools.media.audio` / 媒体理解 | 支持 | -| 流式语音转文本 | Voice Call `streaming.provider: "openai"` | 支持 | -| 实时语音 | Voice Call `realtime.provider: "openai"` | 支持 | -| Embeddings | memory embedding provider | 支持 | +| 聊天 / Responses | `openai/` 模型提供商 | 是 | +| Codex 订阅模型 | `openai/` 搭配 `openai-codex` 身份验证 | 是 | +| 服务端 Web 搜索 | 原生 OpenAI Responses 工具 | 是,在启用 Web 搜索且未固定 provider 时 | +| 图像 | `image_generate` | 是 | +| 视频 | `video_generate` | 是 | +| 文本转语音 | `messages.tts.provider: "openai"` / `tts` | 是 | +| 批量语音转文本 | `tools.media.audio` / 媒体理解 | 是 | +| 流式语音转文本 | Voice Call `streaming.provider: "openai"` | 是 | +| 实时语音 | Voice Call `realtime.provider: "openai"` | 是 | +| Embeddings | memory embedding provider | 是 | ## 入门指南 -请选择你偏好的认证方式,并按照相应步骤进行设置。 +选择你偏好的身份验证方式,并按照设置步骤进行。 - - **最适合:** 直接 API 访问和按用量计费。 + + **最适合:** 直接 API 访问和按使用量计费。 - - 在 [OpenAI Platform dashboard](https://platform.openai.com/api-keys) 中创建或复制一个 API key。 + + 从 [OpenAI Platform 控制台](https://platform.openai.com/api-keys) 创建或复制一个 API 密钥。 ```bash openclaw onboard --auth-choice openai-api-key ``` - 或者直接传入 key: + 或直接传入密钥: ```bash openclaw onboard --openai-api-key "$OPENAI_API_KEY" @@ -66,15 +66,15 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 - ### 路由摘要 + ### 路径摘要 - | 模型引用 | 路由 | 认证 | + | 模型引用 | 路径 | 身份验证 | |-----------|-------|------| | `openai/gpt-5.5` | 直接 OpenAI Platform API | `OPENAI_API_KEY` | | `openai/gpt-5.5-pro` | 直接 OpenAI Platform API | `OPENAI_API_KEY` | - `openai-codex/*` 仍然作为旧版兼容别名被接受,但新配置应使用 `openai/*`。 + `openai-codex/*` 仍可作为旧版兼容别名使用,但新的配置应使用 `openai/*`。 ### 配置示例 @@ -87,13 +87,13 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 ``` - OpenClaw **不会**暴露 `openai/gpt-5.3-codex-spark`。实时 OpenAI API 请求会拒绝该模型,而当前 Codex 目录也没有暴露它。 + OpenClaw **不**提供 `openai/gpt-5.3-codex-spark`。实际的 OpenAI API 请求会拒绝该模型,而当前 Codex 目录也未提供它。 - **最适合:** 使用你的 ChatGPT/Codex 订阅,而不是单独的 API key。Codex 云需要 ChatGPT 登录。 + **最适合:** 使用你的 ChatGPT/Codex 订阅,而不是单独的 API 密钥。Codex cloud 需要 ChatGPT 登录。 @@ -107,7 +107,7 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 openclaw models auth login --provider openai-codex ``` - 对于无头或不适合 localhost 回调的设置,请添加 `--device-code`,通过 ChatGPT 设备码流程登录,而不是使用 localhost 浏览器回调: + 对于无头环境或不适合回调的设置,可以添加 `--device-code`,通过 ChatGPT 设备码流程登录,而不是使用 localhost 浏览器回调: ```bash openclaw models auth login --provider openai-codex --device-code @@ -125,14 +125,14 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 - ### 路由摘要 + ### 路径摘要 - | 模型引用 | 路由 | 认证 | + | 模型引用 | 路径 | 身份验证 | |-----------|-------|------| | `openai/gpt-5.5` | ChatGPT/Codex OAuth | Codex 登录 | - `openai-codex/*` 和 `codex/*` 模型引用是旧版兼容别名。对于认证/profile 命令,请继续使用 `openai-codex` provider id。 + `openai-codex/*` 和 `codex/*` 模型引用是旧版兼容别名。对于身份验证/配置文件命令,请继续使用 `openai-codex` provider id。 ### 配置示例 @@ -144,24 +144,28 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 ``` - 新手引导不再从 `~/.codex` 导入 OAuth 材料。请使用浏览器 OAuth(默认)或上述设备码流程登录——OpenClaw 会在自己的智能体认证存储中管理得到的凭证。 + 新手引导不再从 `~/.codex` 导入 OAuth 材料。请使用浏览器 OAuth(默认)或上述设备码流程登录——OpenClaw 会在自己的智能体身份验证存储中管理生成的凭证。 ### 状态指示器 - 聊天 `/status` 会显示当前会话使用的是哪个内置 harness。默认 PI harness 显示为 `Runner: pi (embedded)`,不会添加额外徽章。当选择的是内置 Codex app-server harness 时,`/status` 会在 `Fast` 后附加非 PI harness id,例如 - `Fast · codex`。现有会话会保留其已记录的 harness id,因此如果你更改了 `embeddedHarness`,并希望 `/status` 反映新的 PI/Codex 选择,请使用 `/new` 或 `/reset`。 + 聊天 `/status` 会显示当前 + 会话正在使用哪个嵌入式 harness。默认的 PI harness 显示为 `Runner: pi (embedded)`,并且 + 不会添加单独的标记。当选择内置的 Codex app-server harness 时, + `/status` 会在 `Fast` 后附加非 PI harness id,例如 + `Fast · codex`。现有会话会保留其记录的 harness id,因此如果你在更改 `embeddedHarness` 后希望 `/status` + 反映新的 PI/Codex 选择,请使用 `/new` 或 `/reset`。 ### 上下文窗口上限 - OpenClaw 将模型元数据与运行时上下文上限视为两个独立值。 + OpenClaw 将模型元数据和运行时上下文上限视为两个独立的值。 对于通过 Codex OAuth 使用的 `openai/gpt-5.5`: - 原生 `contextWindow`:`1000000` - 默认运行时 `contextTokens` 上限:`272000` - 这个较小的默认上限在实践中具有更好的延迟和质量特性。你可以通过 `contextTokens` 覆盖它: + 实际使用中,较小的默认上限通常具有更好的延迟和质量表现。你可以使用 `contextTokens` 进行覆盖: ```json5 { @@ -176,7 +180,7 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 ``` - 请使用 `contextWindow` 声明原生模型元数据。请使用 `contextTokens` 限制运行时上下文预算。 + 使用 `contextWindow` 声明原生模型元数据。使用 `contextTokens` 限制运行时上下文预算。 @@ -184,15 +188,18 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 ## 图像生成 -内置 `openai` 插件通过 `image_generate` 工具注册图像生成能力。 +内置的 `openai` 插件通过 `image_generate` 工具注册图像生成功能。 +它通过同一个 `openai/gpt-image-2` 模型引用,同时支持基于 OpenAI API 密钥的图像生成和基于 Codex OAuth 的图像生成。 -| 能力 | 值 | -| ------------------------- | ---------------------------------- | -| 默认模型 | `openai/gpt-image-2` | -| 每次请求最大图像数 | 4 | -| 编辑模式 | 启用(最多 5 张参考图) | -| 尺寸覆盖 | 支持,包括 2K/4K 尺寸 | -| 宽高比 / 分辨率 | 不会转发到 OpenAI Images API | +| 能力 | OpenAI API 密钥 | Codex OAuth | +| ------------------------- | ---------------------------------- | ------------------------------------ | +| 模型引用 | `openai/gpt-image-2` | `openai/gpt-image-2` | +| 身份验证 | `OPENAI_API_KEY` | OpenAI Codex OAuth 登录 | +| 传输 | OpenAI Images API | Codex Responses 后端 | +| 每次请求的最大图像数 | 4 | 4 | +| 编辑模式 | 已启用(最多 5 张参考图像) | 已启用(最多 5 张参考图像) | +| 尺寸覆盖 | 支持,包括 2K/4K 尺寸 | 支持,包括 2K/4K 尺寸 | +| 宽高比 / 分辨率 | 不会转发到 OpenAI Images API | 在安全情况下映射为受支持的尺寸 | ```json5 { @@ -205,43 +212,36 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 ``` -共享工具参数、provider 选择和故障转移行为请参阅[图像生成](/zh-CN/tools/image-generation)。 +参见 [Image Generation](/zh-CN/tools/image-generation),了解共享工具参数、provider 选择和故障切换行为。 -`gpt-image-2` 是 OpenAI 文生图和图像编辑的默认模型。 -`gpt-image-1` 仍可作为显式模型覆盖使用,但新的 OpenAI 图像工作流应使用 `openai/gpt-image-2`。 +`gpt-image-2` 是 OpenAI 文生图和图像编辑的默认模型。`gpt-image-1` 仍可作为显式模型覆盖使用,但新的 OpenAI 图像工作流应使用 `openai/gpt-image-2`。 -`openai-codex` provider 也会通过 OpenAI Codex OAuth 为图像生成和参考图像编辑暴露 `gpt-image-2`。 -当智能体已通过 Codex OAuth 登录、但没有 `OPENAI_API_KEY` 时,请使用 -`openai-codex/gpt-image-2`。 +对于 Codex OAuth 安装,请继续使用相同的 `openai/gpt-image-2` 引用。如果没有 +`OPENAI_API_KEY`,OpenClaw 会解析为 `openai-codex` auth profile 存储的 OAuth 访问令牌, +并通过 Codex Responses 后端发送图像请求,因此这一路径无需公开的 OpenAI Images API 密钥也可使用。 生成: ``` -/tool image_generate model=openai/gpt-image-2 prompt="A polished launch poster for OpenClaw on macOS" size=3840x2160 count=1 -``` - -使用 Codex OAuth 生成: - -``` -/tool image_generate model=openai-codex/gpt-image-2 prompt="A polished launch poster for OpenClaw on macOS" size=3840x2160 count=1 +/tool image_generate model=openai/gpt-image-2 prompt="为 macOS 上的 OpenClaw 制作一张精美的发布海报" size=3840x2160 count=1 ``` 编辑: ``` -/tool image_generate model=openai/gpt-image-2 prompt="Preserve the object shape, change the material to translucent glass" image=/path/to/reference.png size=1024x1536 +/tool image_generate model=openai/gpt-image-2 prompt="保留物体形状,将材质改为半透明玻璃" image=/path/to/reference.png size=1024x1536 ``` ## 视频生成 -内置 `openai` 插件通过 `video_generate` 工具注册视频生成能力。 +内置的 `openai` 插件通过 `video_generate` 工具注册视频生成功能。 | 能力 | 值 | | ---------------- | --------------------------------------------------------------------------------- | | 默认模型 | `openai/sora-2` | | 模式 | 文生视频、图生视频、单视频编辑 | -| 参考输入 | 1 张图片或 1 个视频 | +| 参考输入 | 1 张图像或 1 个视频 | | 尺寸覆盖 | 支持 | | 其他覆盖 | `aspectRatio`、`resolution`、`audio`、`watermark` 会被忽略,并给出工具警告 | @@ -256,20 +256,20 @@ OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 ``` -共享工具参数、provider 选择和故障转移行为请参阅[视频生成](/zh-CN/tools/video-generation)。 +参见 [Video Generation](/zh-CN/tools/video-generation),了解共享工具参数、provider 选择和故障切换行为。 ## GPT-5 提示词贡献 -OpenClaw 会为跨 provider 的 GPT-5 家族运行添加一个共享 GPT-5 提示词贡献。它按模型 id 应用,因此 `openai/gpt-5.5`、`openrouter/openai/gpt-5.5`、`opencode/gpt-5.5` 以及其他兼容的 GPT-5 引用都会收到相同的覆盖层。较旧的 GPT-4.x 模型则不会。 +OpenClaw 会为跨 provider 的 GPT-5 系列运行添加共享的 GPT-5 提示词贡献。它按模型 id 生效,因此 `openai/gpt-5.5`、`openrouter/openai/gpt-5.5`、`opencode/gpt-5.5` 以及其他兼容的 GPT-5 引用都会收到相同的覆盖层。较旧的 GPT-4.x 模型则不会。 -内置的原生 Codex harness 会通过 Codex app-server 开发者指令使用相同的 GPT-5 行为和心跳覆盖,因此当 `openai/gpt-5.x` 会话被强制使用 `embeddedHarness.runtime: "codex"` 时,也会保留相同的执行跟进和主动心跳指导,即使 Codex 拥有该 harness 提示词的其余部分。 +内置的原生 Codex harness 通过 Codex app-server 开发者指令使用相同的 GPT-5 行为和心跳覆盖层,因此即使其余 harness 提示词由 Codex 接管,强制通过 `embeddedHarness.runtime: "codex"` 运行的 `openai/gpt-5.x` 会话仍会保留相同的后续执行和主动心跳指导。 -GPT-5 提示词贡献增加了一个带标签的行为契约,用于人格保持、执行安全、工具纪律、输出形状、完成检查和验证。渠道专用的回复和静默消息行为则仍保留在共享 OpenClaw system prompt 和出站投递策略中。GPT-5 指导会始终为匹配模型启用。友好交互风格层是独立的,并且可配置。 +GPT-5 贡献为人格持续性、执行安全、工具纪律、输出结构、完成检查和验证添加了带标签的行为契约。特定渠道的回复和静默消息行为仍保留在共享的 OpenClaw 系统提示词和出站传递策略中。对于匹配的模型,GPT-5 指导始终启用。友好的交互风格层是独立且可配置的。 | 值 | 效果 | | ---------------------- | ------------------------------------------- | -| `"friendly"`(默认) | 启用友好交互风格层 | +| `"friendly"`(默认) | 启用友好的交互风格层 | | `"on"` | `"friendly"` 的别名 | | `"off"` | 仅禁用友好风格层 | @@ -295,30 +295,30 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于人格保 -运行时值不区分大小写,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。 +这些值在运行时不区分大小写,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。 -当未设置共享的 `agents.defaults.promptOverlays.gpt5.personality` 时,仍会读取旧版 `plugins.entries.openai.config.personality` 作为兼容回退。 +旧版 `plugins.entries.openai.config.personality` 仍会作为兼容性回退项读取,当未设置共享的 `agents.defaults.promptOverlays.gpt5.personality` 配置时会使用它。 -## 语音和语音处理 +## 语音与音频 - 内置 `openai` 插件会为 `messages.tts` 界面注册语音合成能力。 + 内置的 `openai` 插件为 `messages.tts` 界面注册了语音合成功能。 | 设置 | 配置路径 | 默认值 | |---------|------------|---------| | 模型 | `messages.tts.providers.openai.model` | `gpt-4o-mini-tts` | - | 语音 | `messages.tts.providers.openai.voice` | `coral` | - | 速度 | `messages.tts.providers.openai.speed` | (未设置) | + | 音色 | `messages.tts.providers.openai.voice` | `coral` | + | 语速 | `messages.tts.providers.openai.speed` | (未设置) | | 指令 | `messages.tts.providers.openai.instructions` | (未设置,仅 `gpt-4o-mini-tts` 支持) | - | 格式 | `messages.tts.providers.openai.responseFormat` | 语音便签为 `opus`,文件为 `mp3` | - | API key | `messages.tts.providers.openai.apiKey` | 回退到 `OPENAI_API_KEY` | + | 格式 | `messages.tts.providers.openai.responseFormat` | 语音便笺为 `opus`,文件为 `mp3` | + | API 密钥 | `messages.tts.providers.openai.apiKey` | 回退到 `OPENAI_API_KEY` | | Base URL | `messages.tts.providers.openai.baseUrl` | `https://api.openai.com/v1` | - 可用模型:`gpt-4o-mini-tts`、`tts-1`、`tts-1-hd`。可用语音:`alloy`、`ash`、`ballad`、`cedar`、`coral`、`echo`、`fable`、`juniper`、`marin`、`onyx`、`nova`、`sage`、`shimmer`、`verse`。 + 可用模型:`gpt-4o-mini-tts`、`tts-1`、`tts-1-hd`。可用音色:`alloy`、`ash`、`ballad`、`cedar`、`coral`、`echo`、`fable`、`juniper`、`marin`、`onyx`、`nova`、`sage`、`shimmer`、`verse`。 ```json5 { @@ -333,22 +333,23 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于人格保 ``` - 设置 `OPENAI_TTS_BASE_URL` 可覆盖 TTS 的 base URL,而不会影响聊天 API 端点。 + 设置 `OPENAI_TTS_BASE_URL` 可覆盖 TTS Base URL,而不会影响聊天 API 端点。 - 内置 `openai` 插件会通过 - OpenClaw 的媒体理解转写界面注册批量语音转文本能力。 + 内置的 `openai` 插件通过 + OpenClaw 的媒体理解转录界面注册了批量语音转文本功能。 - 默认模型:`gpt-4o-transcribe` - 端点:OpenAI REST `/v1/audio/transcriptions` - 输入路径:multipart 音频文件上传 - - 在 OpenClaw 中,凡是入站音频转写使用 - `tools.media.audio` 的地方都支持它,包括 Discord 语音频道片段和渠道音频附件 + - 在 OpenClaw 中,只要入站音频转录使用 + `tools.media.audio`,就支持该功能,包括 Discord 语音频道片段和渠道 + 音频附件 - 若要强制对入站音频转写使用 OpenAI: + 要强制对入站音频转录使用 OpenAI: ```json5 { @@ -368,12 +369,13 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于人格保 } ``` - 当共享音频媒体配置或单次转写请求提供语言和提示词提示时,这些提示会转发给 OpenAI。 + 当由共享音频媒体配置或按次转录请求提供语言和提示词时, + 这些提示会转发给 OpenAI。 - 内置 `openai` 插件会为 Voice Call 插件注册实时转录能力。 + 内置的 `openai` 插件为 Voice Call 插件注册了实时转录功能。 | 设置 | 配置路径 | 默认值 | |---------|------------|---------| @@ -382,25 +384,25 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于人格保 | 提示词 | `...openai.prompt` | (未设置) | | 静音时长 | `...openai.silenceDurationMs` | `800` | | VAD 阈值 | `...openai.vadThreshold` | `0.5` | - | API key | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` | + | API 密钥 | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` | - 它使用 WebSocket 连接到 `wss://api.openai.com/v1/realtime`,并采用 G.711 u-law(`g711_ulaw` / `audio/pcmu`)音频。这一流式 provider 用于 Voice Call 的实时转录路径;而 Discord 语音当前仍是录制短片段,并使用批量 `tools.media.audio` 转写路径。 + 使用到 `wss://api.openai.com/v1/realtime` 的 WebSocket 连接,音频格式为 G.711 u-law(`g711_ulaw` / `audio/pcmu`)。此流式 provider 用于 Voice Call 的实时转录路径;Discord 语音当前仍会录制短片段,并改用批量 `tools.media.audio` 转录路径。 - 内置 `openai` 插件会为 Voice Call 插件注册实时语音能力。 + 内置的 `openai` 插件为 Voice Call 插件注册了实时语音功能。 | 设置 | 配置路径 | 默认值 | |---------|------------|---------| | 模型 | `plugins.entries.voice-call.config.realtime.providers.openai.model` | `gpt-realtime-1.5` | - | 语音 | `...openai.voice` | `alloy` | + | 音色 | `...openai.voice` | `alloy` | | Temperature | `...openai.temperature` | `0.8` | | VAD 阈值 | `...openai.vadThreshold` | `0.5` | | 静音时长 | `...openai.silenceDurationMs` | `500` | - | API key | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` | + | API 密钥 | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` | 通过 `azureEndpoint` 和 `azureDeployment` 配置键支持 Azure OpenAI。支持双向工具调用。使用 G.711 u-law 音频格式。 @@ -411,24 +413,29 @@ GPT-5 提示词贡献增加了一个带标签的行为契约,用于人格保 ## Azure OpenAI 端点 -内置的 `openai` provider 可以通过覆盖 base URL,将目标指向一个 Azure OpenAI 资源以进行图像生成。在图像生成路径上,OpenClaw 会检测 `models.providers.openai.baseUrl` 中的 Azure 主机名,并自动切换到 Azure 的请求形状。 +内置的 `openai` provider 可通过覆盖 base URL,将图像生成请求定向到 Azure OpenAI 资源。在图像生成路径上,OpenClaw +会检测 `models.providers.openai.baseUrl` 中的 Azure 主机名,并自动切换为 +Azure 的请求格式。 实时语音使用单独的配置路径 -(`plugins.entries.voice-call.config.realtime.providers.openai.azureEndpoint`),不会受到 `models.providers.openai.baseUrl` 的影响。其 Azure 设置请参阅[语音和语音处理](#voice-and-speech) 下 **实时语音** 手风琴部分。 +(`plugins.entries.voice-call.config.realtime.providers.openai.azureEndpoint`), +不受 `models.providers.openai.baseUrl` 影响。有关其实时语音的 Azure +设置,请参见 [语音与音频](#voice-and-speech) 下的 **实时语音** +折叠面板。 -在以下情况下使用 Azure OpenAI: +以下情况适合使用 Azure OpenAI: - 你已经拥有 Azure OpenAI 订阅、配额或企业协议 - 你需要 Azure 提供的区域数据驻留或合规控制 -- 你希望将流量保留在现有 Azure 租户内部 +- 你希望将流量保留在现有的 Azure 租户内 ### 配置 -若要通过内置 `openai` provider 使用 Azure 进行图像生成,请将 +若要通过内置 `openai` provider 使用 Azure 图像生成,请将 `models.providers.openai.baseUrl` 指向你的 Azure 资源,并将 `apiKey` 设置为 -Azure OpenAI key(而不是 OpenAI Platform key): +Azure OpenAI 密钥(而非 OpenAI Platform 密钥): ```json5 { @@ -443,92 +450,96 @@ Azure OpenAI key(而不是 OpenAI Platform key): } ``` -OpenClaw 会识别以下 Azure 主机后缀,并将其用于 Azure 图像生成路由: +OpenClaw 会为 Azure 图像生成 +路径识别以下 Azure 主机后缀: - `*.openai.azure.com` - `*.services.ai.azure.com` - `*.cognitiveservices.azure.com` -对于识别出的 Azure 主机上的图像生成请求,OpenClaw 会: +对于发送到已识别 Azure 主机的图像生成请求,OpenClaw 会: -- 发送 `api-key` 标头,而不是 `Authorization: Bearer` -- 使用部署作用域路径(`/openai/deployments/{deployment}/...`) -- 在每个请求后追加 `?api-version=...` +- 发送 `api-key` 请求头,而不是 `Authorization: Bearer` +- 使用以部署为范围的路径(`/openai/deployments/{deployment}/...`) +- 为每个请求附加 `?api-version=...` -其他 base URL(公共 OpenAI、兼容 OpenAI 的代理)仍使用标准 -OpenAI 图像请求形状。 +其他 base URL(公共 OpenAI、兼容 OpenAI 的代理)将继续使用标准 +OpenAI 图像请求格式。 -`openai` provider 的图像生成路径使用 Azure 路由功能,要求 -OpenClaw 版本为 2026.4.22 或更高。更早版本会将任意自定义 -`openai.baseUrl` 视为公共 OpenAI 端点,并在 Azure 图像部署上失败。 +`openai` provider 的图像生成路径的 Azure 路由要求 +OpenClaw 2026.4.22 或更高版本。更早版本会将任何自定义 +`openai.baseUrl` 视为公共 OpenAI 端点,因此在 Azure +图像部署上会失败。 -### API 版本 + ### API 版本 -设置 `AZURE_OPENAI_API_VERSION` 可为 -Azure 图像生成路径固定特定的 Azure 预览版或 GA 版本: + 设置 `AZURE_OPENAI_API_VERSION` 以为 Azure 图像生成路径固定特定的 Azure 预览版或 GA 版本: -```bash -export AZURE_OPENAI_API_VERSION="2024-12-01-preview" -``` + ```bash + export AZURE_OPENAI_API_VERSION="2024-12-01-preview" + ``` 当该变量未设置时,默认值为 `2024-12-01-preview`。 - ### 模型名称即部署名称 + ### 模型名称就是部署名称 - Azure OpenAI 会将模型绑定到部署。对于通过内置 `openai` provider 路由的 Azure 图像生成请求,OpenClaw 中的 `model` 字段必须是你在 Azure 门户中配置的**Azure 部署名称**,而不是公共 OpenAI 模型 id。 + Azure OpenAI 将模型绑定到部署。对于通过内置 `openai` provider 路由的 Azure 图像生成请求,OpenClaw 中的 `model` 字段 + 必须是你在 Azure 门户中配置的**Azure 部署名称**,而不是公共 OpenAI 模型 id。 - 如果你创建了一个名为 `gpt-image-2-prod` 的部署,并让它提供 `gpt-image-2`: + 如果你创建了一个名为 `gpt-image-2-prod` 的部署来提供 `gpt-image-2`: ``` - /tool image_generate model=openai/gpt-image-2-prod prompt="A clean poster" size=1024x1024 count=1 + /tool image_generate model=openai/gpt-image-2-prod prompt="一张简洁的海报" size=1024x1024 count=1 ``` 同样的部署名称规则也适用于通过内置 `openai` provider 路由的图像生成调用。 ### 区域可用性 - Azure 图像生成当前仅在部分区域可用 + Azure 图像生成目前仅在部分区域可用 (例如 `eastus2`、`swedencentral`、`polandcentral`、`westus3`、 - `uaenorth`)。在创建部署之前,请先检查 Microsoft 当前的 - 区域列表,并确认你的区域提供了对应模型。 + `uaenorth`)。在创建部署之前,请先查看 Microsoft 最新的区域列表, + 并确认你的区域提供了特定模型。 ### 参数差异 - Azure OpenAI 和公共 OpenAI 并不总是接受相同的图像参数。 - Azure 可能会拒绝公共 OpenAI 可接受的某些选项(例如在 `gpt-image-2` 上某些 - `background` 值),或者只在特定模型版本中暴露这些选项。这些差异来自 Azure 和底层模型,而不是 OpenClaw。如果 Azure 请求因校验错误而失败,请检查 Azure 门户中你的具体部署和 API 版本所支持的参数集。 + Azure OpenAI 与公共 OpenAI 并不总是接受相同的图像参数。 + Azure 可能会拒绝公共 OpenAI 允许的选项(例如 `gpt-image-2` 上的某些 + `background` 值),或者仅在特定模型版本中提供这些选项。这些差异来自 Azure 和底层模型,而不是 + OpenClaw。如果 Azure 请求因验证错误而失败,请在 + Azure 门户中检查你的特定部署和 API 版本所支持的参数集。 Azure OpenAI 使用原生传输和兼容行为,但不会接收 - OpenClaw 的隐藏归因标头——请参阅[高级配置](#advanced-configuration)下 - **原生与兼容 OpenAI 路由** 手风琴部分。 + OpenClaw 的隐藏归因请求头——参见 [Advanced configuration](#advanced-configuration) 下 **原生路由与 OpenAI 兼容路由** + 折叠面板。 - 对于 Azure 上的聊天或 Responses 流量(超出图像生成范围),请使用 - 新手引导流程或专门的 Azure provider 配置——仅设置 `openai.baseUrl` - 并不会自动启用 Azure 的 API/认证形状。还存在一个独立的 - `azure-openai-responses/*` provider;请参阅下方 - Server-side compaction 手风琴部分。 + 对于 Azure 上的聊天或 Responses 流量(图像生成之外),请使用 + 新手引导流程或专用的 Azure provider 配置——仅设置 `openai.baseUrl` + 不会自动采用 Azure 的 API/身份验证格式。存在一个单独的 + `azure-openai-responses/*` provider;请参见下方的 + 服务端压缩折叠面板。 ## 高级配置 - - OpenClaw 对 `openai/*` 和 `openai-codex/*` 都默认使用 WebSocket 优先并回退到 SSE(`"auto"`)。 + + 对于 `openai/*` 和 `openai-codex/*`,OpenClaw 都采用 WebSocket 优先并在失败时回退到 SSE(`"auto"`)。 在 `"auto"` 模式下,OpenClaw 会: - - 对一次早期 WebSocket 失败重试一次,然后回退到 SSE - - 失败后,将 WebSocket 标记为约 60 秒降级,并在冷却期间使用 SSE + - 在回退到 SSE 之前,重试一次早期 WebSocket 失败 + - 发生失败后,将 WebSocket 标记为降级约 60 秒,并在冷却期间使用 SSE - 为重试和重连附加稳定的会话与轮次身份标头 - - 跨不同传输变体统一用量计数器(`input_tokens` / `prompt_tokens`) + - 在不同传输变体之间规范化使用量计数器(`input_tokens` / `prompt_tokens`) | 值 | 行为 | |-------|----------| - | `"auto"`(默认) | WebSocket 优先,SSE 回退 | - | `"sse"` | 强制仅使用 SSE | - | `"websocket"` | 强制仅使用 WebSocket | + | `"auto"`(默认) | WebSocket 优先,失败时回退到 SSE | + | `"sse"` | 仅强制使用 SSE | + | `"websocket"` | 仅强制使用 WebSocket | ```json5 { @@ -551,7 +562,7 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" - OpenClaw 默认会为 `openai/*` 启用 WebSocket 预热,以减少首轮延迟。 + OpenClaw 默认对 `openai/*` 启用 WebSocket 预热,以减少首轮延迟。 ```json5 // 禁用预热 @@ -570,13 +581,13 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" - - OpenClaw 为 `openai/*` 暴露了一个共享 fast mode 开关: + + OpenClaw 为 `openai/*` 提供共享的快速模式切换: - **聊天/UI:** `/fast status|on|off` - **配置:** `agents.defaults.models["/"].params.fastMode` - 启用后,OpenClaw 会将 fast mode 映射为 OpenAI priority processing(`service_tier = "priority"`)。已有的 `service_tier` 值会被保留,fast mode 不会重写 `reasoning` 或 `text.verbosity`。 + 启用后,OpenClaw 会将快速模式映射为 OpenAI 优先处理(`service_tier = "priority"`)。现有的 `service_tier` 值会被保留,快速模式不会重写 `reasoning` 或 `text.verbosity`。 ```json5 { @@ -591,13 +602,13 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" ``` - 会话覆盖优先于配置。在 Sessions UI 中清除会话覆盖后,会话会回到配置中的默认值。 + 会话级覆盖优先于配置。在 Sessions UI 中清除会话覆盖后,会话将恢复为配置的默认值。 - - OpenAI 的 API 通过 `service_tier` 暴露优先级处理能力。你可以在 OpenClaw 中按模型设置它: + + OpenAI 的 API 通过 `service_tier` 提供优先处理。你可以在 OpenClaw 中按模型设置它: ```json5 { @@ -614,21 +625,21 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" 支持的值:`auto`、`default`、`flex`、`priority`。 - `serviceTier` 只会转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由任一 provider,OpenClaw 会保持 `service_tier` 不变。 + `serviceTier` 仅会转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由任一 provider,OpenClaw 会保持 `service_tier` 不变。 - - 对于直接的 OpenAI Responses 模型(位于 `api.openai.com` 上的 `openai/*`),OpenClaw 会自动启用 server-side compaction: + + 对于直接的 OpenAI Responses 模型(位于 `api.openai.com` 的 `openai/*`),OpenClaw 会自动启用服务端压缩: - - 强制设置 `store: true`(除非模型兼容性设置 `supportsStore: false`) + - 强制设置 `store: true`(除非模型兼容性将 `supportsStore` 设为 `false`) - 注入 `context_management: [{ type: "compaction", compact_threshold: ... }]` - - 默认 `compact_threshold`:`contextWindow` 的 70%(若不可用则为 `80000`) + - 默认 `compact_threshold`:`contextWindow` 的 70%(不可用时为 `80000`) - 对于像 Azure OpenAI Responses 这样的兼容端点很有用: + 适用于 Azure OpenAI Responses 等兼容端点: ```json5 { @@ -680,13 +691,13 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" - `responsesServerCompaction` 只控制 `context_management` 注入。直接的 OpenAI Responses 模型仍会强制 `store: true`,除非兼容性设置了 `supportsStore: false`。 + `responsesServerCompaction` 仅控制 `context_management` 注入。直接 OpenAI Responses 模型仍会强制使用 `store: true`,除非兼容性将 `supportsStore` 设为 `false`。 - - 对于 `openai/*` 上的 GPT-5 家族运行,OpenClaw 可使用更严格的内置执行契约: + + 对于 `openai/*` 上的 GPT-5 系列运行,OpenClaw 可以使用更严格的嵌入式执行契约: ```json5 { @@ -698,33 +709,33 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" } ``` - 启用 `strict-agentic` 后,OpenClaw 会: - - 当存在可用工具动作时,不再将仅有规划的轮次视为成功进展 - - 使用一个立即行动的 steer 重试该轮次 - - 对于较大工作量自动启用 `update_plan` - - 如果模型持续规划却不行动,则显式呈现 blocked 状态 + 使用 `strict-agentic` 时,OpenClaw 会: + - 当存在可用工具操作时,不再将仅有计划的轮次视为成功进展 + - 使用“立即行动”的引导重试该轮次 + - 对于较大工作自动启用 `update_plan` + - 如果模型持续规划而不执行操作,则明确显示阻塞状态 - 仅作用于 OpenAI 和 Codex 的 GPT-5 家族运行。其他提供商和较旧模型家族仍保持默认行为。 + 仅适用于 OpenAI 和 Codex 的 GPT-5 系列运行。其他 provider 和较旧的模型系列保持默认行为。 - - OpenClaw 会将直接 OpenAI、Codex 和 Azure OpenAI 端点与通用的兼容 OpenAI `/v1` 代理区别对待: + + OpenClaw 会区别对待直接 OpenAI、Codex 和 Azure OpenAI 端点,以及通用的 OpenAI 兼容 `/v1` 代理: **原生路由**(`openai/*`、Azure OpenAI): - 仅对支持 OpenAI `none` effort 的模型保留 `reasoning: { effort: "none" }` - - 对于会拒绝 `reasoning.effort: "none"` 的模型或代理,省略禁用 reasoning 的设置 + - 对于拒绝 `reasoning.effort: "none"` 的模型或代理,省略禁用的 reasoning - 默认将工具 schema 设为严格模式 - - 仅在已验证的原生主机上附加隐藏归因标头 - - 保留 OpenAI 专属请求整形(`service_tier`、`store`、reasoning 兼容性、提示词缓存提示) + - 仅在已验证的原生主机上附加隐藏归因请求头 + - 保留 OpenAI 专用的请求格式(`service_tier`、`store`、reasoning 兼容性、提示词缓存提示) **代理/兼容路由:** - 使用更宽松的兼容行为 - - 不会强制严格工具 schema,也不会添加原生专属标头 + - 不强制严格工具 schema 或原生专用请求头 - Azure OpenAI 使用原生传输和兼容行为,但不会接收隐藏归因标头。 + Azure OpenAI 使用原生传输和兼容行为,但不会接收隐藏归因请求头。 @@ -733,7 +744,7 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" - 选择 provider、模型引用和故障转移行为。 + 选择 provider、模型引用和故障切换行为。 共享图像工具参数和 provider 选择。 @@ -741,7 +752,7 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview" 共享视频工具参数和 provider 选择。 - - 认证细节和凭证复用规则。 + + 身份验证详情和凭证复用规则。 diff --git a/docs/zh-CN/reference/memory-config.md b/docs/zh-CN/reference/memory-config.md index 1ecf6939c..da6ca117c 100644 --- a/docs/zh-CN/reference/memory-config.md +++ b/docs/zh-CN/reference/memory-config.md @@ -1,96 +1,91 @@ --- read_when: - - 你想配置 memory 搜索提供商或 embedding 模型 - - 你想设置 QMD 后端】【。analysis to=functions.read commentary 天天中彩票中奖json 787 content omitted due to length? - - 你想调优混合搜索、MMR 或时间衰减 - - 你想启用多模态 memory 索引 -summary: 有关 memory 搜索、embedding 提供商、QMD、混合搜索和多模态索引的全部配置项 -title: Memory 配置参考 + - 你想要配置内存搜索提供商或嵌入模型 + - 你想要设置 QMD 后端 + - 你想要调整混合搜索、MMR 或时间衰减 + - 你想要启用多模态内存索引 +summary: 内存搜索、嵌入提供商、QMD、混合搜索和多模态索引的所有配置项 +title: 内存配置参考 x-i18n: - generated_at: "2026-04-23T21:03:29Z" + generated_at: "2026-04-23T21:49:30Z" model: gpt-5.4 provider: openai - source_hash: 2e179b955ee0532805ee254d79217b66c093def534c2ef3952d955b3b05de8ca + source_hash: e8f91c15c149feb1a351585d246f3155ce56164cbda3e773dd63ebfa6c1b63b7 source_path: reference/memory-config.md workflow: 15 --- -本页列出了 OpenClaw memory 搜索的所有配置项。关于概念性概览,请参见: +此页面列出了 OpenClaw 内存搜索的所有配置项。有关概念概览,请参阅: -- [Memory Overview](/zh-CN/concepts/memory) —— memory 的工作方式 -- [Builtin Engine](/zh-CN/concepts/memory-builtin) —— 默认 SQLite 后端 -- [QMD Engine](/zh-CN/concepts/memory-qmd) —— 本地优先 sidecar -- [Memory Search](/zh-CN/concepts/memory-search) —— 搜索管线和调优 +- [Memory Overview](/zh-CN/concepts/memory) —— 内存的工作方式 +- [Builtin Engine](/zh-CN/concepts/memory-builtin) —— 默认的 SQLite 后端 +- [QMD Engine](/zh-CN/concepts/memory-qmd) —— 本地优先的 sidecar +- [Memory Search](/zh-CN/concepts/memory-search) —— 搜索流水线与调优 - [Active Memory](/zh-CN/concepts/active-memory) —— 为交互式会话启用 memory 子智能体 -除特别说明外,所有 memory 搜索设置都位于 -`openclaw.json` 的 `agents.defaults.memorySearch` 下。 +除非另有说明,所有内存搜索设置都位于 `openclaw.json` 中的 `agents.defaults.memorySearch` 下。 -如果你在找的是 **active memory** 功能开关和子智能体配置, -它位于 `plugins.entries.active-memory` 下,而不是 `memorySearch`。 +如果你要查找 **active memory** 功能开关和子智能体配置,这些内容位于 `plugins.entries.active-memory` 下,而不是 `memorySearch`。 Active memory 使用双门控模型: -1. 插件必须已启用,并且目标指向当前智能体 id +1. 必须启用该插件,并将其目标指向当前智能体 ID 2. 请求必须是符合条件的交互式持久聊天会话 -关于激活模型、插件自有配置、transcript 持久化和安全上线模式, -请参见 [Active Memory](/zh-CN/concepts/active-memory)。 +有关激活模型、插件自有配置、转录持久化以及安全发布模式,请参阅 [Active Memory](/zh-CN/concepts/active-memory)。 --- ## 提供商选择 -| 键 | 类型 | 默认值 | 描述 | +| Key | Type | Default | Description | | ---------- | --------- | ---------------- | ------------------------------------------------------------------------------------------------------------- | -| `provider` | `string` | 自动检测 | Embedding 适配器 id:`bedrock`、`gemini`、`github-copilot`、`local`、`mistral`、`ollama`、`openai`、`voyage` | -| `model` | `string` | 提供商默认值 | Embedding 模型名称 | -| `fallback` | `string` | `"none"` | 主适配器失败时使用的回退适配器 id | -| `enabled` | `boolean` | `true` | 启用或禁用 memory 搜索 | +| `provider` | `string` | 自动检测 | 嵌入适配器 ID:`bedrock`、`gemini`、`github-copilot`、`local`、`mistral`、`ollama`、`openai`、`voyage` | +| `model` | `string` | 提供商默认值 | 嵌入模型名称 | +| `fallback` | `string` | `"none"` | 当主提供商失败时使用的回退适配器 ID | +| `enabled` | `boolean` | `true` | 启用或禁用内存搜索 | ### 自动检测顺序 当未设置 `provider` 时,OpenClaw 会选择第一个可用项: -1. `local` —— 如果配置了 `memorySearch.local.modelPath` 且文件存在。 -2. `github-copilot` —— 如果 GitHub Copilot token 可解析(环境变量或 auth profile)。 -3. `openai` —— 如果 OpenAI key 可解析。 -4. `gemini` —— 如果 Gemini key 可解析。 -5. `voyage` —— 如果 Voyage key 可解析。 -6. `mistral` —— 如果 Mistral key 可解析。 -7. `bedrock` —— 如果 AWS SDK 凭证链可解析(实例角色、access key、profile、SSO、web identity 或共享配置)。 +1. `local` —— 如果已配置 `memorySearch.local.modelPath` 且文件存在。 +2. `github-copilot` —— 如果可以解析到 GitHub Copilot 令牌(环境变量或认证配置文件)。 +3. `openai` —— 如果可以解析到 OpenAI 密钥。 +4. `gemini` —— 如果可以解析到 Gemini 密钥。 +5. `voyage` —— 如果可以解析到 Voyage 密钥。 +6. `mistral` —— 如果可以解析到 Mistral 密钥。 +7. `bedrock` —— 如果 AWS SDK 凭证链可解析(实例角色、访问密钥、profile、SSO、web identity 或共享配置)。 支持 `ollama`,但不会自动检测(请显式设置)。 -### API key 解析 +### API 密钥解析 -远程 embeddings 需要 API key。Bedrock 则改用 AWS SDK 默认 -凭证链(实例角色、SSO、access key)。 +远程嵌入需要 API 密钥。Bedrock 则使用 AWS SDK 默认凭证链(实例角色、SSO、访问密钥)。 -| 提供商 | 环境变量 | 配置键 | +| Provider | Env var | Config key | | -------------- | -------------------------------------------------- | --------------------------------- | -| Bedrock | AWS 凭证链 | 不需要 API key | -| Gemini | `GEMINI_API_KEY` | `models.providers.google.apiKey` | -| GitHub Copilot | `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN` | 通过设备登录的 auth profile | -| Mistral | `MISTRAL_API_KEY` | `models.providers.mistral.apiKey` | -| Ollama | `OLLAMA_API_KEY`(占位) | -- | -| OpenAI | `OPENAI_API_KEY` | `models.providers.openai.apiKey` | -| Voyage | `VOYAGE_API_KEY` | `models.providers.voyage.apiKey` | +| Bedrock | AWS 凭证链 | 不需要 API 密钥 | +| Gemini | `GEMINI_API_KEY` | `models.providers.google.apiKey` | +| GitHub Copilot | `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN` | 通过设备登录的认证配置文件 | +| Mistral | `MISTRAL_API_KEY` | `models.providers.mistral.apiKey` | +| Ollama | `OLLAMA_API_KEY`(占位符) | -- | +| OpenAI | `OPENAI_API_KEY` | `models.providers.openai.apiKey` | +| Voyage | `VOYAGE_API_KEY` | `models.providers.voyage.apiKey` | -Codex OAuth 仅覆盖 chat/completions,不满足 embedding -请求。 +Codex OAuth 仅适用于聊天/补全,不满足嵌入请求的要求。 --- ## 远程端点配置 -用于自定义 OpenAI 兼容端点,或覆盖提供商默认值: +用于自定义 OpenAI 兼容端点或覆盖提供商默认值: -| 键 | 类型 | 描述 | -| ---------------- | -------- | -------------------------------------------------- | -| `remote.baseUrl` | `string` | 自定义 API base URL | -| `remote.apiKey` | `string` | 覆盖 API key | -| `remote.headers` | `object` | 额外 HTTP 请求头(与提供商默认值合并) | +| Key | Type | Description | +| ---------------- | -------- | --------------------------------------- | +| `remote.baseUrl` | `string` | 自定义 API 基础 URL | +| `remote.apiKey` | `string` | 覆盖 API 密钥 | +| `remote.headers` | `object` | 额外的 HTTP 请求头(与提供商默认值合并) | ```json5 { @@ -111,24 +106,23 @@ Codex OAuth 仅覆盖 chat/completions,不满足 embedding --- -## Gemini 专用配置 +## Gemini 专属配置 -| 键 | 类型 | 默认值 | 描述 | -| ---------------------- | -------- | ---------------------- | ------------------------------------------ | -| `model` | `string` | `gemini-embedding-001` | 也支持 `gemini-embedding-2-preview` | -| `outputDimensionality` | `number` | `3072` | 对于 Embedding 2:768、1536 或 3072 | +| Key | Type | Default | Description | +| ---------------------- | -------- | ---------------------- | ----------------------------------------- | +| `model` | `string` | `gemini-embedding-001` | 也支持 `gemini-embedding-2-preview` | +| `outputDimensionality` | `number` | `3072` | 对于 Embedding 2,可选 768、1536 或 3072 | -更改模型或 `outputDimensionality` 会触发自动全量重建索引。 +更改模型或 `outputDimensionality` 会触发自动全量重新索引。 --- -## Bedrock embedding 配置 +## Bedrock 嵌入配置 -Bedrock 使用 AWS SDK 默认凭证链 —— 无需 API key。 -如果 OpenClaw 运行在带有 Bedrock 权限实例角色的 EC2 上,只需设置 -provider 和 model: +Bedrock 使用 AWS SDK 默认凭证链 —— 不需要 API 密钥。 +如果 OpenClaw 运行在启用了 Bedrock 实例角色的 EC2 上,只需设置 provider 和 model: ```json5 { @@ -143,47 +137,45 @@ provider 和 model: } ``` -| 键 | 类型 | 默认值 | 描述 | -| ---------------------- | -------- | ------------------------------ | ------------------------------- | -| `model` | `string` | `amazon.titan-embed-text-v2:0` | 任意 Bedrock embedding 模型 ID | -| `outputDimensionality` | `number` | 模型默认值 | 对于 Titan V2:256、512 或 1024 | +| Key | Type | Default | Description | +| ---------------------- | -------- | ------------------------------ | ------------------------------ | +| `model` | `string` | `amazon.titan-embed-text-v2:0` | 任意 Bedrock 嵌入模型 ID | +| `outputDimensionality` | `number` | 模型默认值 | 对于 Titan V2,可选 256、512 或 1024 | ### 支持的模型 -支持以下模型(带有家族检测和默认维度): +以下模型受支持(包含系列检测和默认维度): -| 模型 ID | 提供商 | 默认维度 | 可配置维度 | +| Model ID | Provider | Default Dims | Configurable Dims | | ------------------------------------------ | ---------- | ------------ | -------------------- | -| `amazon.titan-embed-text-v2:0` | Amazon | 1024 | 256, 512, 1024 | -| `amazon.titan-embed-text-v1` | Amazon | 1536 | -- | -| `amazon.titan-embed-g1-text-02` | Amazon | 1536 | -- | -| `amazon.titan-embed-image-v1` | Amazon | 1024 | -- | -| `amazon.nova-2-multimodal-embeddings-v1:0` | Amazon | 1024 | 256, 384, 1024, 3072 | -| `cohere.embed-english-v3` | Cohere | 1024 | -- | -| `cohere.embed-multilingual-v3` | Cohere | 1024 | -- | -| `cohere.embed-v4:0` | Cohere | 1536 | 256-1536 | -| `twelvelabs.marengo-embed-3-0-v1:0` | TwelveLabs | 512 | -- | -| `twelvelabs.marengo-embed-2-7-v1:0` | TwelveLabs | 1024 | -- | +| `amazon.titan-embed-text-v2:0` | Amazon | 1024 | 256, 512, 1024 | +| `amazon.titan-embed-text-v1` | Amazon | 1536 | -- | +| `amazon.titan-embed-g1-text-02` | Amazon | 1536 | -- | +| `amazon.titan-embed-image-v1` | Amazon | 1024 | -- | +| `amazon.nova-2-multimodal-embeddings-v1:0` | Amazon | 1024 | 256, 384, 1024, 3072 | +| `cohere.embed-english-v3` | Cohere | 1024 | -- | +| `cohere.embed-multilingual-v3` | Cohere | 1024 | -- | +| `cohere.embed-v4:0` | Cohere | 1536 | 256-1536 | +| `twelvelabs.marengo-embed-3-0-v1:0` | TwelveLabs | 512 | -- | +| `twelvelabs.marengo-embed-2-7-v1:0` | TwelveLabs | 1024 | -- | -带吞吐后缀的变体(例如 `amazon.titan-embed-text-v1:2:8k`)会继承 -基础模型的配置。 +带吞吐量后缀的变体(例如 `amazon.titan-embed-text-v1:2:8k`)会继承基础模型的配置。 ### 认证 Bedrock 认证使用标准 AWS SDK 凭证解析顺序: 1. 环境变量(`AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`) -2. SSO token 缓存 -3. Web identity token 凭证 +2. SSO 令牌缓存 +3. Web identity 令牌凭证 4. 共享凭证和配置文件 5. ECS 或 EC2 元数据凭证 -区域会从 `AWS_REGION`、`AWS_DEFAULT_REGION`、 -`amazon-bedrock` 提供商的 `baseUrl` 中解析,或默认使用 `us-east-1`。 +区域将从 `AWS_REGION`、`AWS_DEFAULT_REGION`、`amazon-bedrock` 提供商的 `baseUrl` 中解析,或默认使用 `us-east-1`。 ### IAM 权限 -IAM 角色或用户需要: +IAM 角色或用户需要具备: ```json { @@ -193,7 +185,7 @@ IAM 角色或用户需要: } ``` -若要最小权限,请将 `InvokeModel` 限定到具体模型: +为了实现最小权限,应将 `InvokeModel` 限定到特定模型: ``` arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0 @@ -201,15 +193,16 @@ arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0 --- -## 本地 embedding 配置 +## 本地嵌入配置 -| 键 | 类型 | 默认值 | 描述 | -| --------------------- | -------- | ---------------------- | ------------------------------- | -| `local.modelPath` | `string` | 自动下载 | GGUF 模型文件路径 | -| `local.modelCacheDir` | `string` | node-llama-cpp 默认值 | 下载模型的缓存目录 | +| Key | Type | Default | Description | +| --------------------- | ------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `local.modelPath` | `string` | 自动下载 | GGUF 模型文件路径 | +| `local.modelCacheDir` | `string` | node-llama-cpp 默认值 | 已下载模型的缓存目录 | +| `local.contextSize` | `number \| "auto"` | `4096` | 嵌入上下文的上下文窗口大小。4096 可覆盖典型分块(128–512 个 token),同时限制非权重 VRAM 占用。在受限主机上可降至 1024–2048。`"auto"` 使用模型训练时的最大值——不建议用于 8B+ 模型(Qwen3-Embedding-8B:40 960 个 token → 约 32 GB VRAM,而在 4096 时约为 8.8 GB)。 | 默认模型:`embeddinggemma-300m-qat-Q8_0.gguf`(约 0.6 GB,自动下载)。 -需要原生构建:`pnpm approve-builds` 然后 `pnpm rebuild node-llama-cpp`。 +需要原生构建:`pnpm approve-builds`,然后执行 `pnpm rebuild node-llama-cpp`。 --- @@ -217,28 +210,28 @@ arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0 全部位于 `memorySearch.query.hybrid` 下: -| 键 | 类型 | 默认值 | 描述 | -| --------------------- | --------- | ------- | ---------------------------------- | -| `enabled` | `boolean` | `true` | 启用混合 BM25 + 向量搜索 | -| `vectorWeight` | `number` | `0.7` | 向量分数权重(0-1) | -| `textWeight` | `number` | `0.3` | BM25 分数权重(0-1) | -| `candidateMultiplier` | `number` | `4` | 候选池大小乘数 | +| Key | Type | Default | Description | +| --------------------- | --------- | ------- | ------------------------------ | +| `enabled` | `boolean` | `true` | 启用混合 BM25 + 向量搜索 | +| `vectorWeight` | `number` | `0.7` | 向量分数权重(0-1) | +| `textWeight` | `number` | `0.3` | BM25 分数权重(0-1) | +| `candidateMultiplier` | `number` | `4` | 候选池大小乘数 | ### MMR(多样性) -| 键 | 类型 | 默认值 | 描述 | -| ------------- | --------- | ------- | ------------------------------------ | -| `mmr.enabled` | `boolean` | `false` | 启用 MMR 重排序 | -| `mmr.lambda` | `number` | `0.7` | 0 = 最大多样性,1 = 最大相关性 | +| Key | Type | Default | Description | +| ------------- | --------- | ------- | ---------------------------------- | +| `mmr.enabled` | `boolean` | `false` | 启用 MMR 重新排序 | +| `mmr.lambda` | `number` | `0.7` | 0 = 最大多样性,1 = 最大相关性 | ### 时间衰减(新近性) -| 键 | 类型 | 默认值 | 描述 | -| ---------------------------- | --------- | ------- | ------------------------- | -| `temporalDecay.enabled` | `boolean` | `false` | 启用新近性加权 | -| `temporalDecay.halfLifeDays` | `number` | `30` | 每 N 天分数减半 | +| Key | Type | Default | Description | +| ---------------------------- | --------- | ------- | -------------------- | +| `temporalDecay.enabled` | `boolean` | `false` | 启用新近性加权 | +| `temporalDecay.halfLifeDays` | `number` | `30` | 每 N 天分数减半 | -常青文件(`MEMORY.md`、`memory/` 中非日期命名文件)永远不会衰减。 +常青文件(`MEMORY.md`、`memory/` 中无日期的文件)永远不会衰减。 ### 完整示例 @@ -263,11 +256,11 @@ arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0 --- -## 额外 memory 路径 +## 其他内存路径 -| 键 | 类型 | 描述 | -| ------------ | ---------- | ---------------------------------------- | -| `extraPaths` | `string[]` | 额外需要索引的目录或文件 | +| Key | Type | Description | +| ------------ | ---------- | ------------------------------ | +| `extraPaths` | `string[]` | 要建立索引的其他目录或文件 | ```json5 { @@ -281,152 +274,137 @@ arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0 } ``` -路径可以是绝对路径,也可以相对于工作区。目录会递归扫描 -`.md` 文件。符号链接处理取决于当前后端: -内置引擎会忽略符号链接,而 QMD 会遵循底层 QMD -扫描器行为。 +路径可以是绝对路径,也可以是相对于工作区的路径。目录会递归扫描 `.md` 文件。符号链接的处理取决于当前启用的后端:内置引擎会忽略符号链接,而 QMD 则遵循底层 QMD 扫描器的行为。 -对于按智能体作用域的跨智能体 transcript 搜索,请使用 -`agents.list[].memorySearch.qmd.extraCollections`,而不是 `memory.qmd.paths`。 -这些额外 collection 使用相同的 `{ path, name, pattern? }` 结构,但 -它们会按智能体合并,并且当路径指向当前工作区之外时, -可以保留显式共享名称。 -如果相同的已解析路径同时出现在 `memory.qmd.paths` 和 -`memorySearch.qmd.extraCollections` 中,QMD 会保留第一项并跳过 -重复项。 +对于按智能体作用域划分的跨智能体转录搜索,请使用 `agents.list[].memorySearch.qmd.extraCollections`,而不是 `memory.qmd.paths`。这些额外集合使用相同的 `{ path, name, pattern? }` 结构,但会按智能体合并,并且当路径指向当前工作区之外时,可以保留显式共享名称。 +如果同一个解析后的路径同时出现在 `memory.qmd.paths` 和 `memorySearch.qmd.extraCollections` 中,QMD 会保留第一项并跳过重复项。 --- -## 多模态 memory(Gemini) +## 多模态内存(Gemini) -使用 Gemini Embedding 2 为图像和音频与 Markdown 一起建立索引: +使用 Gemini Embedding 2 将图像和音频与 Markdown 一起建立索引: -| 键 | 类型 | 默认值 | 描述 | -| ------------------------- | ---------- | ---------- | -------------------------------------- | -| `multimodal.enabled` | `boolean` | `false` | 启用多模态索引 | -| `multimodal.modalities` | `string[]` | -- | `["image"]`、`["audio"]` 或 `["all"]` | -| `multimodal.maxFileBytes` | `number` | `10000000` | 用于索引的最大文件大小 | +| Key | Type | Default | Description | +| ------------------------- | ---------- | ---------- | ----------------------------------- | +| `multimodal.enabled` | `boolean` | `false` | 启用多模态索引 | +| `multimodal.modalities` | `string[]` | -- | `["image"]`、`["audio"]` 或 `["all"]` | +| `multimodal.maxFileBytes` | `number` | `10000000` | 建立索引时允许的最大文件大小 | -仅适用于 `extraPaths` 中的文件。默认 memory 根目录仍然只处理 Markdown。 -要求使用 `gemini-embedding-2-preview`。`fallback` 必须为 `"none"`。 +仅适用于 `extraPaths` 中的文件。默认内存根目录仍然只支持 Markdown。 +需要 `gemini-embedding-2-preview`。`fallback` 必须为 `"none"`。 支持的格式:`.jpg`、`.jpeg`、`.png`、`.webp`、`.gif`、`.heic`、`.heif` (图像);`.mp3`、`.wav`、`.ogg`、`.opus`、`.m4a`、`.aac`、`.flac`(音频)。 --- -## Embedding 缓存 +## 嵌入缓存 -| 键 | 类型 | 默认值 | 描述 | -| ------------------ | --------- | ------- | -------------------------------- | -| `cache.enabled` | `boolean` | `false` | 在 SQLite 中缓存 chunk embedding | -| `cache.maxEntries` | `number` | `50000` | 最大缓存 embedding 数 | +| Key | Type | Default | Description | +| ------------------ | --------- | ------- | ------------------------------- | +| `cache.enabled` | `boolean` | `false` | 在 SQLite 中缓存分块嵌入 | +| `cache.maxEntries` | `number` | `50000` | 最大缓存嵌入数量 | -可防止在重建索引或 transcript 更新时,对未更改的文本重复进行 embedding。 +可防止在重新索引或更新转录时,对未更改的文本重复生成嵌入。 --- ## 批量索引 -| 键 | 类型 | 默认值 | 描述 | -| ----------------------------- | --------- | ------- | -------------------------- | -| `remote.batch.enabled` | `boolean` | `false` | 启用批量 embedding API | -| `remote.batch.concurrency` | `number` | `2` | 并行批处理作业数 | -| `remote.batch.wait` | `boolean` | `true` | 等待批处理完成 | -| `remote.batch.pollIntervalMs` | `number` | -- | 轮询间隔 | -| `remote.batch.timeoutMinutes` | `number` | -- | 批处理超时 | +| Key | Type | Default | Description | +| ----------------------------- | --------- | ------- | ------------------------ | +| `remote.batch.enabled` | `boolean` | `false` | 启用批量嵌入 API | +| `remote.batch.concurrency` | `number` | `2` | 并行批处理任务数 | +| `remote.batch.wait` | `boolean` | `true` | 等待批处理完成 | +| `remote.batch.pollIntervalMs` | `number` | -- | 轮询间隔 | +| `remote.batch.timeoutMinutes` | `number` | -- | 批处理超时时间 | -适用于 `openai`、`gemini` 和 `voyage`。对于大规模回填, -OpenAI 批处理通常速度最快、成本最低。 +适用于 `openai`、`gemini` 和 `voyage`。对于大规模回填,OpenAI 批处理通常最快且成本最低。 --- -## 会话 memory 搜索(实验性) +## 会话内存搜索(实验性) -为会话 transcript 建立索引,并通过 `memory_search` 暴露出来: +为会话转录建立索引,并通过 `memory_search` 暴露: -| 键 | 类型 | 默认值 | 描述 | +| Key | Type | Default | Description | | ----------------------------- | ---------- | ------------ | --------------------------------------- | -| `experimental.sessionMemory` | `boolean` | `false` | 启用会话索引 | -| `sources` | `string[]` | `["memory"]` | 添加 `"sessions"` 以包含 transcript | -| `sync.sessions.deltaBytes` | `number` | `100000` | 触发重建索引的字节阈值 | -| `sync.sessions.deltaMessages` | `number` | `50` | 触发重建索引的消息阈值 | +| `experimental.sessionMemory` | `boolean` | `false` | 启用会话索引 | +| `sources` | `string[]` | `["memory"]` | 添加 `"sessions"` 以包含转录 | +| `sync.sessions.deltaBytes` | `number` | `100000` | 触发重新索引的字节阈值 | +| `sync.sessions.deltaMessages` | `number` | `50` | 触发重新索引的消息阈值 | -会话索引是选择启用功能,并且异步运行。结果可能会有轻微 -滞后。会话日志存储在磁盘上,因此请将文件系统访问视为信任 -边界。 +会话索引需要显式启用,并以异步方式运行。结果可能会有轻微滞后。会话日志保存在磁盘上,因此应将文件系统访问视为信任边界。 --- ## SQLite 向量加速(sqlite-vec) -| 键 | 类型 | 默认值 | 描述 | -| ---------------------------- | --------- | ------- | --------------------------------- | -| `store.vector.enabled` | `boolean` | `true` | 使用 sqlite-vec 执行向量查询 | -| `store.vector.extensionPath` | `string` | bundled | 覆盖 sqlite-vec 路径 | +| Key | Type | Default | Description | +| ---------------------------- | --------- | ------- | ---------------------------------- | +| `store.vector.enabled` | `boolean` | `true` | 使用 sqlite-vec 执行向量查询 | +| `store.vector.extensionPath` | `string` | bundled | 覆盖 sqlite-vec 路径 | -当 sqlite-vec 不可用时,OpenClaw 会自动回退到进程内 cosine -similarity。 +当 sqlite-vec 不可用时,OpenClaw 会自动回退到进程内余弦相似度计算。 --- ## 索引存储 -| 键 | 类型 | 默认值 | 描述 | -| --------------------- | -------- | ------------------------------------- | ------------------------------------------- | -| `store.path` | `string` | `~/.openclaw/memory/{agentId}.sqlite` | 索引位置(支持 `{agentId}` token) | -| `store.fts.tokenizer` | `string` | `unicode61` | FTS5 tokenizer(`unicode61` 或 `trigram`) | +| Key | Type | Default | Description | +| --------------------- | -------- | ------------------------------------- | --------------------------------------- | +| `store.path` | `string` | `~/.openclaw/memory/{agentId}.sqlite` | 索引位置(支持 `{agentId}` 占位符) | +| `store.fts.tokenizer` | `string` | `unicode61` | FTS5 分词器(`unicode61` 或 `trigram`) | --- ## QMD 后端配置 -设置 `memory.backend = "qmd"` 以启用。所有 QMD 设置位于 +设置 `memory.backend = "qmd"` 以启用。所有 QMD 设置都位于 `memory.qmd` 下: -| 键 | 类型 | 默认值 | 描述 | -| ------------------------ | --------- | -------- | -------------------------------------------- | -| `command` | `string` | `qmd` | QMD 可执行文件路径 | -| `searchMode` | `string` | `search` | 搜索命令:`search`、`vsearch`、`query` | -| `includeDefaultMemory` | `boolean` | `true` | 自动索引 `MEMORY.md` + `memory/**/*.md` | -| `paths[]` | `array` | -- | 额外路径:`{ name, path, pattern? }` | -| `sessions.enabled` | `boolean` | `false` | 为会话 transcript 建立索引 | -| `sessions.retentionDays` | `number` | -- | Transcript 保留期 | -| `sessions.exportDir` | `string` | -- | 导出目录 | +| Key | Type | Default | Description | +| ------------------------ | --------- | -------- | ------------------------------------------ | +| `command` | `string` | `qmd` | QMD 可执行文件路径 | +| `searchMode` | `string` | `search` | 搜索命令:`search`、`vsearch`、`query` | +| `includeDefaultMemory` | `boolean` | `true` | 自动索引 `MEMORY.md` + `memory/**/*.md` | +| `paths[]` | `array` | -- | 额外路径:`{ name, path, pattern? }` | +| `sessions.enabled` | `boolean` | `false` | 为会话转录建立索引 | +| `sessions.retentionDays` | `number` | -- | 转录保留时长 | +| `sessions.exportDir` | `string` | -- | 导出目录 | -OpenClaw 会优先使用当前的 QMD collection 和 MCP 查询形态,但仍通过回退到旧版 `--mask` collection 标志 -和旧版 MCP 工具名来兼容较老版本的 QMD。 +OpenClaw 优先使用当前 QMD collection 和 MCP 查询结构,但也会通过回退到旧版 `--mask` collection 标志和旧版 MCP 工具名称,在需要时继续兼容较旧的 QMD 版本。 -QMD 模型覆盖保留在 QMD 侧,而不是 OpenClaw 配置中。如果你需要全局 -覆盖 QMD 模型,请在 gateway -运行时环境中设置诸如 `QMD_EMBED_MODEL`、`QMD_RERANK_MODEL` 和 `QMD_GENERATE_MODEL` 这样的环境变量。 +QMD 模型覆盖配置保留在 QMD 侧,而不是 OpenClaw 配置中。如果你需要全局覆盖 QMD 的模型,请在 Gateway 网关运行时环境中设置环境变量,例如 +`QMD_EMBED_MODEL`、`QMD_RERANK_MODEL` 和 `QMD_GENERATE_MODEL`。 ### 更新计划 -| 键 | 类型 | 默认值 | 描述 | -| ------------------------- | --------- | ------- | ------------------------------------- | -| `update.interval` | `string` | `5m` | 刷新间隔 | -| `update.debounceMs` | `number` | `15000` | 文件更改防抖时间 | -| `update.onBoot` | `boolean` | `true` | 启动时刷新 | -| `update.waitForBootSync` | `boolean` | `false` | 在刷新完成前阻塞启动 | -| `update.embedInterval` | `string` | -- | 单独的 embed 频率 | -| `update.commandTimeoutMs` | `number` | -- | QMD 命令超时 | -| `update.updateTimeoutMs` | `number` | -- | QMD update 操作超时 | -| `update.embedTimeoutMs` | `number` | -- | QMD embed 操作超时 | +| Key | Type | Default | Description | +| ------------------------- | --------- | ------- | -------------------------------- | +| `update.interval` | `string` | `5m` | 刷新间隔 | +| `update.debounceMs` | `number` | `15000` | 文件变更防抖时间 | +| `update.onBoot` | `boolean` | `true` | 启动时刷新 | +| `update.waitForBootSync` | `boolean` | `false` | 启动时阻塞,直到刷新完成 | +| `update.embedInterval` | `string` | -- | 单独的嵌入执行周期 | +| `update.commandTimeoutMs` | `number` | -- | QMD 命令超时时间 | +| `update.updateTimeoutMs` | `number` | -- | QMD 更新操作超时时间 | +| `update.embedTimeoutMs` | `number` | -- | QMD 嵌入操作超时时间 | ### 限制 -| 键 | 类型 | 默认值 | 描述 | -| ------------------------- | -------- | ------- | -------------------------- | -| `limits.maxResults` | `number` | `6` | 最大搜索结果数 | -| `limits.maxSnippetChars` | `number` | -- | 限制片段长度 | -| `limits.maxInjectedChars` | `number` | -- | 限制注入总字符数 | -| `limits.timeoutMs` | `number` | `4000` | 搜索超时 | +| Key | Type | Default | Description | +| ------------------------- | -------- | ------- | ---------------------- | +| `limits.maxResults` | `number` | `6` | 最大搜索结果数 | +| `limits.maxSnippetChars` | `number` | -- | 限制摘要长度 | +| `limits.maxInjectedChars` | `number` | -- | 限制注入的总字符数 | +| `limits.timeoutMs` | `number` | `4000` | 搜索超时时间 | -### 范围 +### 作用域 -控制哪些会话可以接收 QMD 搜索结果。其 schema 与 -[`session.sendPolicy`](/zh-CN/gateway/configuration-reference#session) 相同: +用于控制哪些会话可以接收 QMD 搜索结果。使用与 +[`session.sendPolicy`](/zh-CN/gateway/configuration-reference#session) 相同的 schema: ```json5 { @@ -441,21 +419,20 @@ QMD 模型覆盖保留在 QMD 侧,而不是 OpenClaw 配置中。如果你需 } ``` -内置默认值允许 direct 和 channel 会话,同时仍拒绝 -group。 +随附的默认配置允许 direct 和 channel 会话,同时仍然拒绝 group。 -默认值为仅私信。`match.keyPrefix` 匹配规范化后的会话键; -`match.rawKeyPrefix` 匹配包含 `agent::` 的原始键。 +默认仅限私信。`match.keyPrefix` 匹配规范化后的会话键; +`match.rawKeyPrefix` 匹配原始键,包括 `agent::`。 ### 引用 `memory.citations` 适用于所有后端: -| 值 | 行为 | -| ---------------- | --------------------------------------------------- | -| `auto`(默认) | 在片段中包含 `Source: ` 页脚 | -| `on` | 始终包含页脚 | -| `off` | 省略页脚(路径仍会在内部传给智能体) | +| Value | Behavior | +| ---------------- | ----------------------------------------- | +| `auto`(默认) | 在摘要中包含 `Source: ` 页脚 | +| `on` | 始终包含页脚 | +| `off` | 省略页脚(路径仍会在内部传递给智能体) | ### 完整 QMD 示例 @@ -483,19 +460,18 @@ group。 ## Dreaming Dreaming 配置位于 `plugins.entries.memory-core.config.dreaming` 下, -而不是 `agents.defaults.memorySearch`。 +而不是 `agents.defaults.memorySearch` 下。 -Dreaming 作为一次计划好的完整 sweep 运行,并将内部 light/deep/REM 阶段作为 -实现细节。 +Dreaming 作为一次计划中的完整扫描运行,并将内部的 light/deep/REM 阶段作为实现细节。 -关于概念行为和斜杠命令,请参见 [Dreaming](/zh-CN/concepts/dreaming)。 +有关概念行为和斜杠命令,请参阅 [Dreaming](/zh-CN/concepts/dreaming)。 ### 用户设置 -| 键 | 类型 | 默认值 | 描述 | -| ----------- | --------- | ----------- | ------------------------------------------------- | -| `enabled` | `boolean` | `false` | 完全启用或禁用 dreaming | -| `frequency` | `string` | `0 3 * * *` | 完整 dreaming sweep 的可选 cron 频率 | +| Key | Type | Default | Description | +| ----------- | --------- | ----------- | ----------------------------------- | +| `enabled` | `boolean` | `false` | 完全启用或禁用 Dreaming | +| `frequency` | `string` | `0 3 * * *` | 可选的完整 Dreaming 扫描 cron 周期 | ### 示例 @@ -519,5 +495,5 @@ Dreaming 作为一次计划好的完整 sweep 运行,并将内部 light/deep/R 说明: - Dreaming 会将机器状态写入 `memory/.dreams/`。 -- Dreaming 会将人类可读的叙事输出写入 `DREAMS.md`(或已有的 `dreams.md`)。 +- Dreaming 会将人类可读的叙事输出写入 `DREAMS.md`(或现有的 `dreams.md`)。 - light/deep/REM 阶段策略和阈值属于内部行为,不是面向用户的配置。 diff --git a/docs/zh-CN/tools/image-generation.md b/docs/zh-CN/tools/image-generation.md index f40760223..205fff1a1 100644 --- a/docs/zh-CN/tools/image-generation.md +++ b/docs/zh-CN/tools/image-generation.md @@ -1,29 +1,29 @@ --- read_when: - 通过智能体生成图像 - - 配置图像生成 providers 和模型 - - 理解 `image_generate` 工具参数 -summary: 使用已配置的 providers(OpenAI、Google Gemini、fal、MiniMax、ComfyUI、Vydra、xAI)生成和编辑图像 + - 配置图像生成提供商和模型 + - 了解 `image_generate` 工具参数 +summary: 使用已配置的提供商(OpenAI、OpenAI Codex OAuth、Google Gemini、fal、MiniMax、ComfyUI、Vydra、xAI)生成和编辑图像 title: 图像生成 x-i18n: - generated_at: "2026-04-23T21:08:28Z" + generated_at: "2026-04-23T21:49:31Z" model: gpt-5.4 provider: openai - source_hash: 2ca23553fa80fbc286046baa2bdb639aab76a24f2d55dc1764085f57b24be29e + source_hash: efba2038e097843053a33f2afe3e98d22a83d79fefc84872c2c7c47dbe888dc0 source_path: tools/image-generation.md workflow: 15 --- -`image_generate` 工具让智能体能够使用你已配置的 providers 创建和编辑图像。生成的图像会自动作为媒体附件附加在智能体回复中发送。 +`image_generate` 工具允许智能体使用你已配置的提供商创建和编辑图像。生成的图像会作为媒体附件自动包含在智能体的回复中。 -只有当至少有一个图像生成 provider 可用时,该工具才会出现。如果你没有在智能体工具中看到 `image_generate`,请配置 `agents.defaults.imageGenerationModel` 或设置 provider API 密钥。 +只有在至少有一个图像生成提供商可用时,此工具才会显示。如果你在智能体的工具中看不到 `image_generate`,请配置 `agents.defaults.imageGenerationModel`、设置提供商 API 密钥,或使用 OpenAI Codex OAuth 登录。 ## 快速开始 -1. 至少为一个 provider 设置 API 密钥(例如 `OPENAI_API_KEY` 或 `GEMINI_API_KEY`)。 -2. 可选地设置你偏好的模型: +1. 为至少一个提供商设置 API 密钥(例如 `OPENAI_API_KEY` 或 `GEMINI_API_KEY`),或使用 OpenAI Codex OAuth 登录。 +2. 可选:设置你偏好的模型: ```json5 { @@ -37,47 +37,48 @@ x-i18n: } ``` -3. 对智能体说:_“生成一张友好龙虾吉祥物的图像。”_ +Codex OAuth 使用相同的 `openai/gpt-image-2` 模型引用。如果没有可用的 `OPENAI_API_KEY`,OpenClaw 会解析现有的 `openai-codex` OAuth 配置文件,并通过 Codex Responses 后端发送图像请求。 -智能体会自动调用 `image_generate`。无需手动加入工具允许列表——只要 provider 可用,它默认就是启用的。 +3. 向智能体发出请求:_“生成一张友好机器人吉祥物的图像。”_ -## 支持的 providers +智能体会自动调用 `image_generate`。无需工具允许列表——当提供商可用时,它默认启用。 -| Provider | 默认模型 | 编辑支持 | API 密钥 | -| ------------ | -------------------------------- | --------------------------------- | ------------------------------------------------------ | -| OpenAI | `gpt-image-2` | 是(最多 4 张图像) | `OPENAI_API_KEY` | -| OpenAI Codex | `gpt-image-2` | 是(最多 4 张图像) | OpenAI Codex OAuth | -| Google | `gemini-3.1-flash-image-preview` | 是 | `GEMINI_API_KEY` 或 `GOOGLE_API_KEY` | -| fal | `fal-ai/flux/dev` | 是 | `FAL_KEY` | -| MiniMax | `image-01` | 是(主体参考) | `MINIMAX_API_KEY` 或 MiniMax OAuth(`minimax-portal`) | -| ComfyUI | `workflow` | 是(1 张图像,由工作流配置) | 云端需要 `COMFY_API_KEY` 或 `COMFY_CLOUD_API_KEY` | -| Vydra | `grok-imagine` | 否 | `VYDRA_API_KEY` | -| xAI | `grok-imagine-image` | 是(最多 5 张图像) | `XAI_API_KEY` | +## 支持的提供商 -使用 `action: "list"` 可以在运行时检查可用 providers 和模型: +| 提供商 | 默认模型 | 编辑支持 | 认证 | +| -------- | -------------------------------- | ---------------------------------- | ----------------------------------------------------- | +| OpenAI | `gpt-image-2` | 是(最多 4 张图像) | `OPENAI_API_KEY` 或 OpenAI Codex OAuth | +| Google | `gemini-3.1-flash-image-preview` | 是 | `GEMINI_API_KEY` 或 `GOOGLE_API_KEY` | +| fal | `fal-ai/flux/dev` | 是 | `FAL_KEY` | +| MiniMax | `image-01` | 是(主体参考) | `MINIMAX_API_KEY` 或 MiniMax OAuth (`minimax-portal`) | +| ComfyUI | `workflow` | 是(1 张图像,由工作流配置) | 云端使用 `COMFY_API_KEY` 或 `COMFY_CLOUD_API_KEY` | +| Vydra | `grok-imagine` | 否 | `VYDRA_API_KEY` | +| xAI | `grok-imagine-image` | 是(最多 5 张图像) | `XAI_API_KEY` | -```text +使用 `action: "list"` 可在运行时检查可用的提供商和模型: + +``` /tool image_generate action=list ``` ## 工具参数 -| 参数 | 类型 | 说明 | -| ------------- | --------- | ---------------------------------------------------------------------------------------- | -| `prompt` | string | 图像生成提示(`action: "generate"` 时必填) | -| `action` | string | `"generate"`(默认)或 `"list"`,用于查看 providers | -| `model` | string | Provider/模型覆盖,例如 `openai/gpt-image-2` | -| `image` | string | 编辑模式下的单张参考图像路径或 URL | -| `images` | string[] | 编辑模式下的多张参考图像(最多 5 张) | -| `size` | string | 尺寸提示:`1024x1024`、`1536x1024`、`1024x1536`、`2048x2048`、`3840x2160` | -| `aspectRatio` | string | 宽高比:`1:1`、`2:3`、`3:2`、`3:4`、`4:3`、`4:5`、`5:4`、`9:16`、`16:9`、`21:9` | -| `resolution` | string | 分辨率提示:`1K`、`2K` 或 `4K` | -| `count` | number | 要生成的图像数量(1–4) | -| `filename` | string | 输出文件名提示 | +| 参数 | 类型 | 说明 | +| ------------- | -------- | ------------------------------------------------------------------------------------- | +| `prompt` | string | 图像生成提示词(`action: "generate"` 时必需) | +| `action` | string | `"generate"`(默认)或 `"list"`,用于查看提供商 | +| `model` | string | 提供商/模型覆盖,例如 `openai/gpt-image-2` | +| `image` | string | 编辑模式下的单张参考图像路径或 URL | +| `images` | string[] | 编辑模式下的多张参考图像(最多 5 张) | +| `size` | string | 尺寸提示:`1024x1024`、`1536x1024`、`1024x1536`、`2048x2048`、`3840x2160` | +| `aspectRatio` | string | 宽高比:`1:1`、`2:3`、`3:2`、`3:4`、`4:3`、`4:5`、`5:4`、`9:16`、`16:9`、`21:9` | +| `resolution` | string | 分辨率提示:`1K`、`2K` 或 `4K` | +| `count` | number | 要生成的图像数量(1–4) | +| `filename` | string | 输出文件名提示 | -并非所有 providers 都支持所有参数。当某个回退 provider 支持的是接近的几何选项而不是精确请求值时,OpenClaw 会在提交前将其重新映射为最接近的受支持 size、aspect ratio 或 resolution。真正不受支持的覆盖项仍会在工具结果中报告。 +并非所有提供商都支持所有参数。当某个回退提供商支持接近的几何选项而非你精确请求的选项时,OpenClaw 会在提交前重新映射为最接近的受支持尺寸、宽高比或分辨率。真正不支持的覆盖项仍会在工具结果中报告。 -工具结果会报告实际应用的设置。当 OpenClaw 在 provider 回退期间重新映射几何参数时,返回的 `size`、`aspectRatio` 和 `resolution` 值会反映实际发送的内容,而 `details.normalization` 则会记录从请求值到应用值的转换过程。 +工具结果会报告实际应用的设置。当 OpenClaw 在提供商回退期间重新映射几何参数时,返回的 `size`、`aspectRatio` 和 `resolution` 值会反映实际发送的内容,而 `details.normalization` 会记录从请求值到应用值的转换。 ## 配置 @@ -96,117 +97,104 @@ x-i18n: } ``` -### Provider 选择顺序 +### 提供商选择顺序 -生成图像时,OpenClaw 会按以下顺序尝试 providers: +生成图像时,OpenClaw 会按以下顺序尝试提供商: -1. 工具调用中的 **`model` 参数**(如果智能体显式指定) +1. 工具调用中的 **`model` 参数**(如果智能体指定了该参数) 2. 配置中的 **`imageGenerationModel.primary`** -3. 按顺序尝试 **`imageGenerationModel.fallbacks`** -4. **自动检测** —— 仅使用基于认证的 provider 默认值: - - 当前默认 provider 优先 - - 其余已注册图像生成 providers,按 provider-id 顺序排列 +3. 按顺序使用 **`imageGenerationModel.fallbacks`** +4. **自动检测** —— 仅使用具备认证支持的提供商默认值: + - 当前默认提供商优先 + - 其余已注册图像生成提供商,按 provider-id 顺序 -如果某个 provider 失败(认证错误、限流等),系统会自动尝试下一个候选项。如果全部失败,错误中会包含每次尝试的详细信息。 +如果某个提供商失败(认证错误、速率限制等),会自动尝试下一个候选项。如果全部失败,错误信息会包含每次尝试的详细信息。 -说明: +注意: -- 自动检测是带认证感知的。只有当 OpenClaw 实际能够认证该 provider 时,该 provider 默认值 - 才会进入候选列表。 -- 自动检测默认启用。若你希望图像 - 生成仅使用显式 `model`、`primary` 和 `fallbacks` - 条目,请设置 - `agents.defaults.mediaGenerationAutoProviderFallback: false`。 -- 使用 `action: "list"` 可以查看当前已注册的 providers、它们的默认模型,以及认证环境变量提示。 +- 自动检测具备认证感知能力。只有当 OpenClaw 实际能够对某个提供商进行认证时,该提供商默认值才会进入候选列表。 +- 自动检测默认启用。如果你希望图像生成仅使用显式的 `model`、`primary` 和 `fallbacks` 条目,请设置 `agents.defaults.mediaGenerationAutoProviderFallback: false`。 +- 使用 `action: "list"` 可检查当前已注册的提供商、它们的默认模型以及认证环境变量提示。 ### 图像编辑 OpenAI、Google、fal、MiniMax、ComfyUI 和 xAI 支持编辑参考图像。传入参考图像路径或 URL: -```text -"Generate a watercolor version of this photo" + image: "/path/to/photo.jpg" +``` +"生成这张照片的水彩版本" + image: "/path/to/photo.jpg" ``` -OpenAI、Google 和 xAI 通过 `images` 参数支持最多 5 张参考图像。fal、MiniMax 和 ComfyUI 支持 1 张。 +OpenAI、Google 和 xAI 通过 `images` 参数最多支持 5 张参考图像。fal、MiniMax 和 ComfyUI 支持 1 张。 ### OpenAI `gpt-image-2` -OpenAI 图像生成默认使用 `openai/gpt-image-2`。较旧的 -`openai/gpt-image-1` 模型仍然可以显式选择,但新的 OpenAI -图像生成和图像编辑请求应使用 `gpt-image-2`。 +OpenAI 图像生成默认使用 `openai/gpt-image-2`。可用时会使用 `OPENAI_API_KEY`。如果未配置 API 密钥,OpenClaw 会复用与 Codex 订阅聊天模型相同的 `openai-codex` OAuth 配置文件,并通过 Codex Responses 后端发送图像请求。较旧的 `openai/gpt-image-1` 模型仍可显式选择,但新的 OpenAI 图像生成和图像编辑请求应使用 `gpt-image-2`。 -`gpt-image-2` 通过同一个 `image_generate` 工具同时支持文生图生成和参考图像 -编辑。OpenClaw 会将 `prompt`、 -`count`、`size` 和参考图像转发给 OpenAI。OpenAI 不会直接接收 -`aspectRatio` 或 `resolution`;在可能的情况下,OpenClaw 会将它们映射为受支持的 -`size`,否则工具会将其报告为被忽略的覆盖项。 +`gpt-image-2` 同时支持文生图生成和通过同一个 `image_generate` 工具进行参考图像编辑。OpenClaw 会将 `prompt`、`count`、`size` 和参考图像转发给 OpenAI。OpenAI 不会直接接收 `aspectRatio` 或 `resolution`;在可能的情况下,OpenClaw 会将它们映射为受支持的 `size`,否则工具会将它们报告为被忽略的覆盖项。 生成一张 4K 横向图像: -```text +``` /tool image_generate action=generate model=openai/gpt-image-2 prompt="A clean editorial poster for OpenClaw image generation" size=3840x2160 count=1 ``` 生成两张方形图像: -```text +``` /tool image_generate action=generate model=openai/gpt-image-2 prompt="Two visual directions for a calm productivity app icon" size=1024x1024 count=2 ``` 编辑一张本地参考图像: -```text +``` /tool image_generate action=generate model=openai/gpt-image-2 prompt="Keep the subject, replace the background with a bright studio setup" image=/path/to/reference.png size=1024x1536 ``` 使用多张参考图像进行编辑: -```text +``` /tool image_generate action=generate model=openai/gpt-image-2 prompt="Combine the character identity from the first image with the color palette from the second" images='["/path/to/character.png","/path/to/palette.jpg"]' size=1536x1024 ``` -如果你希望通过 Azure OpenAI 部署而不是 -`api.openai.com` 来路由 OpenAI 图像生成,请参阅 OpenAI provider 文档中的 [Azure OpenAI 端点](/zh-CN/providers/openai#azure-openai-endpoints)。 +如果你想通过 Azure OpenAI 部署而不是 `api.openai.com` 路由 OpenAI 图像生成,请参阅 OpenAI 提供商文档中的 [Azure OpenAI endpoints](/zh-CN/providers/openai#azure-openai-endpoints)。 MiniMax 图像生成可通过两种内置 MiniMax 认证路径使用: -- API 密钥设置使用 `minimax/image-01` -- OAuth 设置使用 `minimax-portal/image-01` +- `minimax/image-01` 用于 API 密钥配置 +- `minimax-portal/image-01` 用于 OAuth 配置 -## Provider 能力 +## 提供商能力 -| 能力 | OpenAI | Google | fal | MiniMax | ComfyUI | Vydra | xAI | -| --------------------- | ---------------------- | -------------------- | -------------------- | ------------------------- | --------------------------------- | ------- | -------------------- | -| 生成 | 是(最多 4 张) | 是(最多 4 张) | 是(最多 4 张) | 是(最多 9 张) | 是(工作流定义的输出) | 是(1 张) | 是(最多 4 张) | -| 编辑/参考 | 是(最多 5 张图像) | 是(最多 5 张图像) | 是(1 张图像) | 是(1 张图像,主体参考) | 是(1 张图像,由工作流配置) | 否 | 是(最多 5 张图像) | -| 尺寸控制 | 是(最高 4K) | 是 | 是 | 否 | 否 | 否 | 否 | -| 宽高比 | 否 | 是 | 是(仅生成) | 是 | 否 | 否 | 是 | -| 分辨率(1K/2K/4K) | 否 | 是 | 是 | 否 | 否 | 否 | 是(1K/2K) | +| 能力 | OpenAI | Google | fal | MiniMax | ComfyUI | Vydra | xAI | +| --------------------- | -------------------- | -------------------- | ------------------- | -------------------------- | ---------------------------------- | ------- | -------------------- | +| 生成 | 是(最多 4 张) | 是(最多 4 张) | 是(最多 4 张) | 是(最多 9 张) | 是(输出由工作流定义) | 是(1 张) | 是(最多 4 张) | +| 编辑/参考 | 是(最多 5 张图像) | 是(最多 5 张图像) | 是(1 张图像) | 是(1 张图像,主体参考) | 是(1 张图像,由工作流配置) | 否 | 是(最多 5 张图像) | +| 尺寸控制 | 是(最高 4K) | 是 | 是 | 否 | 否 | 否 | 否 | +| 宽高比 | 否 | 是 | 是(仅生成) | 是 | 否 | 否 | 是 | +| 分辨率(1K/2K/4K) | 否 | 是 | 是 | 否 | 否 | 否 | 是(1K/2K) | ### xAI `grok-imagine-image` -内置 xAI provider 会对纯提示请求使用 `/v1/images/generations`, -当存在 `image` 或 `images` 时则使用 `/v1/images/edits`。 +内置 xAI 提供商在仅提示词请求时使用 `/v1/images/generations`,而在存在 `image` 或 `images` 时使用 `/v1/images/edits`。 - 模型:`xai/grok-imagine-image`、`xai/grok-imagine-image-pro` - 数量:最多 4 张 -- 参考:1 个 `image` 或最多 5 个 `images` +- 参考:一个 `image` 或最多五个 `images` - 宽高比:`1:1`、`16:9`、`9:16`、`4:3`、`3:4`、`2:3`、`3:2` - 分辨率:`1K`、`2K` -- 输出:作为 OpenClaw 管理的图像附件返回 +- 输出:作为由 OpenClaw 管理的图像附件返回 -在共享的跨 provider `image_generate` 契约中,OpenClaw 有意不暴露 xAI 原生的 `quality`、`mask`、`user` 或 -其他额外的原生专有宽高比,直到这些控制项在共享契约中存在为止。 +在这些控制项出现在共享的跨提供商 `image_generate` 契约中之前,OpenClaw 有意不公开 xAI 原生的 `quality`、`mask`、`user` 或其他仅原生支持的宽高比选项。 ## 相关内容 -- [工具概览](/zh-CN/tools) —— 所有可用的智能体工具 -- [fal](/zh-CN/providers/fal) —— fal 图像与视频 provider 设置 -- [ComfyUI](/zh-CN/providers/comfy) —— 本地 ComfyUI 与 Comfy Cloud 工作流设置 -- [Google(Gemini)](/zh-CN/providers/google) —— Gemini 图像 provider 设置 -- [MiniMax](/zh-CN/providers/minimax) —— MiniMax 图像 provider 设置 -- [OpenAI](/zh-CN/providers/openai) —— OpenAI Images provider 设置 -- [Vydra](/zh-CN/providers/vydra) —— Vydra 图像、视频与语音设置 -- [xAI](/zh-CN/providers/xai) —— Grok 图像、视频、搜索、代码执行与 TTS 设置 -- [配置参考](/zh-CN/gateway/configuration-reference#agent-defaults) —— `imageGenerationModel` 配置 -- [模型](/zh-CN/concepts/models) —— 模型配置与故障转移 +- [Tools Overview](/zh-CN/tools) — 所有可用的智能体工具 +- [fal](/zh-CN/providers/fal) — fal 图像和视频提供商设置 +- [ComfyUI](/zh-CN/providers/comfy) — 本地 ComfyUI 和 Comfy Cloud 工作流设置 +- [Google (Gemini)](/zh-CN/providers/google) — Gemini 图像提供商设置 +- [MiniMax](/zh-CN/providers/minimax) — MiniMax 图像提供商设置 +- [OpenAI](/zh-CN/providers/openai) — OpenAI Images 提供商设置 +- [Vydra](/zh-CN/providers/vydra) — Vydra 图像、视频和语音设置 +- [xAI](/zh-CN/providers/xai) — Grok 图像、视频、搜索、代码执行和 TTS 设置 +- [Configuration Reference](/zh-CN/gateway/configuration-reference#agent-defaults) — `imageGenerationModel` 配置 +- [Models](/zh-CN/concepts/models) — 模型配置和故障转移