chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
8270fc7bc5
commit
0f085cad6e
@ -1,57 +1,57 @@
|
||||
---
|
||||
read_when:
|
||||
- 检查正在进行或最近已完成的后台工作
|
||||
- 调试分离式智能体运行的传递失败问题
|
||||
- 检查进行中或刚刚完成的后台工作
|
||||
- 调试已分离智能体运行的交付失败问题
|
||||
- 了解后台运行与会话、cron 和心跳之间的关系
|
||||
summary: 用于 ACP 运行、子智能体、隔离的 cron 作业和 CLI 操作的后台任务跟踪
|
||||
title: 后台任务
|
||||
x-i18n:
|
||||
generated_at: "2026-04-23T20:40:43Z"
|
||||
generated_at: "2026-04-26T03:01:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 10f16268ab5cce8c3dfd26c54d8d913c0ac0f9bfb4856ed1bb28b085ddb78528
|
||||
source_hash: 71153c54df90aad2b87b657ad68b3d34c618e5e82d63e0fd0d5c04a7d9182da0
|
||||
source_path: automation/tasks.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
> **在找调度方式吗?** 请参阅[自动化与任务](/zh-CN/automation),以选择合适的机制。本页介绍的是如何**跟踪**后台工作,而不是如何调度它。
|
||||
> **在找调度方式?** 请参阅 [Automation & Tasks](/zh-CN/automation) 以选择合适的机制。本页介绍的是如何**跟踪**后台工作,而不是如何调度它。
|
||||
|
||||
后台任务用于跟踪**主对话会话之外**运行的工作:
|
||||
ACP 运行、子智能体生成、隔离的 cron 作业执行,以及由 CLI 发起的操作。
|
||||
后台任务用于跟踪**在你的主会话之外**运行的工作:
|
||||
ACP 运行、子智能体派生、隔离的 cron 作业执行,以及由 CLI 发起的操作。
|
||||
|
||||
任务**不会**替代会话、cron 作业或心跳——它们是记录分离式工作何时发生、发生了什么以及是否成功的**活动账本**。
|
||||
任务**不会**替代会话、cron 作业或心跳 —— 它们是记录这些分离工作“发生了什么、何时发生、是否成功”的**活动台账**。
|
||||
|
||||
<Note>
|
||||
并非每次智能体运行都会创建任务。心跳轮次和普通交互式聊天不会创建任务。所有 cron 执行、ACP 生成、子智能体生成以及 CLI 智能体命令都会创建任务。
|
||||
并不是每次智能体运行都会创建任务。心跳轮次和普通交互式聊天不会创建任务。所有 cron 执行、ACP 派生、子智能体派生以及 CLI 智能体命令都会创建任务。
|
||||
</Note>
|
||||
|
||||
## TL;DR
|
||||
|
||||
- 任务是**记录**,不是调度器——cron 和心跳决定工作_何时_运行,任务跟踪_发生了什么_。
|
||||
- 任务是**记录**,不是调度器 —— cron 和心跳决定工作_何时_运行,任务负责跟踪_发生了什么_。
|
||||
- ACP、子智能体、所有 cron 作业和 CLI 操作都会创建任务。心跳轮次不会。
|
||||
- 每个任务都会经历 `queued → running → terminal`(succeeded、failed、timed_out、cancelled 或 lost)。
|
||||
- 只要 cron 运行时仍拥有该作业,cron 任务就会保持活动状态;基于聊天的 CLI 任务则只会在其所属的运行上下文仍处于活动状态时保持活动。
|
||||
- 完成是由推送驱动的:分离式工作在完成时可以直接通知,或唤醒请求方的会话 / 心跳,因此状态轮询循环通常不是正确方式。
|
||||
- 隔离的 cron 运行和子智能体完成时,会在最终清理记账前尽力清理其子会话所跟踪的浏览器标签页 / 进程。
|
||||
- 隔离的 cron 投递会在后代子智能体工作仍在收尾时抑制陈旧的中间父级回复,并在后代最终输出先于投递到达时优先使用该输出。
|
||||
- 完成通知会直接投递到某个渠道,或排队等待下一次心跳发送。
|
||||
- `openclaw tasks list` 会显示所有任务;`openclaw tasks audit` 会显示问题。
|
||||
- 终态记录会保留 7 天,然后自动清理。
|
||||
- 只要 cron 运行时仍然持有该作业,cron 任务就会保持活动状态;而基于聊天的 CLI 任务仅在其所属运行上下文仍然处于活动状态时保持活动。
|
||||
- 完成采用推送驱动:分离工作完成时可以直接通知,或唤醒请求者会话/心跳,因此通常不应该使用轮询状态的循环。
|
||||
- 隔离的 cron 运行和子智能体完成时,会尽力为其子会话清理已跟踪的浏览器标签页/进程,然后再执行最终清理记账。
|
||||
- 隔离的 cron 投递会在后代子智能体工作仍在收尾时抑制过时的中间父级回复,并在后代最终输出先到达时优先采用它。
|
||||
- 完成通知会直接投递到渠道,或排队等待下一次心跳。
|
||||
- `openclaw tasks list` 显示所有任务;`openclaw tasks audit` 会显示问题。
|
||||
- 终态记录会保留 7 天,之后自动清理。
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
# 列出所有任务(最新优先)
|
||||
# 列出所有任务(按最新优先)
|
||||
openclaw tasks list
|
||||
|
||||
# 按运行时或状态筛选
|
||||
openclaw tasks list --runtime acp
|
||||
openclaw tasks list --status running
|
||||
|
||||
# 显示特定任务的详细信息(通过 ID、运行 ID 或会话键)
|
||||
# 显示特定任务的详情(通过 ID、run ID 或 session key)
|
||||
openclaw tasks show <lookup>
|
||||
|
||||
# 取消正在运行的任务(终止子会话)
|
||||
# 取消正在运行的任务(会终止子会话)
|
||||
openclaw tasks cancel <lookup>
|
||||
|
||||
# 更改任务的通知策略
|
||||
@ -72,23 +72,23 @@ openclaw tasks flow cancel <lookup>
|
||||
|
||||
## 什么会创建任务
|
||||
|
||||
| 来源 | 运行时类型 | 任务记录创建时机 | 默认通知策略 |
|
||||
| 来源 | 运行时类型 | 何时创建任务记录 | 默认通知策略 |
|
||||
| ---------------------- | ------------ | ------------------------------------------------------ | --------------------- |
|
||||
| ACP 后台运行 | `acp` | 生成 ACP 子会话时 | `done_only` |
|
||||
| 子智能体编排 | `subagent` | 通过 `sessions_spawn` 生成子智能体时 | `done_only` |
|
||||
| Cron 作业(所有类型) | `cron` | 每次 cron 执行时(主会话和隔离执行都算) | `silent` |
|
||||
| ACP 后台运行 | `acp` | 派生子 ACP 会话时 | `done_only` |
|
||||
| 子智能体编排 | `subagent` | 通过 `sessions_spawn` 派生子智能体时 | `done_only` |
|
||||
| cron 作业(所有类型) | `cron` | 每次 cron 执行时(主会话和隔离运行都包括) | `silent` |
|
||||
| CLI 操作 | `cli` | 通过 Gateway 网关运行的 `openclaw agent` 命令 | `silent` |
|
||||
| 智能体媒体作业 | `cli` | 基于会话的 `video_generate` 运行 | `silent` |
|
||||
|
||||
主会话 cron 任务默认使用 `silent` 通知策略——它们会创建记录用于跟踪,但不会生成通知。隔离的 cron 任务同样默认使用 `silent`,但因为它们在各自独立的会话中运行,因此更容易被注意到。
|
||||
主会话 cron 任务默认使用 `silent` 通知策略 —— 它们会创建记录以便跟踪,但不会生成通知。隔离的 cron 任务也默认使用 `silent`,但由于它们在各自独立的会话中运行,因此更容易被看到。
|
||||
|
||||
基于会话的 `video_generate` 运行也使用 `silent` 通知策略。它们仍会创建任务记录,但完成结果会通过内部唤醒返回给原始智能体会话,以便智能体自己编写后续消息并附上生成完成的视频。如果你启用了 `tools.media.asyncCompletion.directSend`,异步 `music_generate` 和 `video_generate` 完成时会先尝试直接投递到渠道,失败后再回退到唤醒请求方会话的路径。
|
||||
基于会话的 `video_generate` 运行也使用 `silent` 通知策略。它们仍会创建任务记录,但完成后会通过内部唤醒返回到原始智能体会话,以便智能体自行编写后续消息并附加完成的视频。如果你启用了 `tools.media.asyncCompletion.directSend`,异步 `music_generate` 和 `video_generate` 完成时会先尝试直接投递到渠道,失败后再回退到唤醒请求者会话的路径。
|
||||
|
||||
当某个基于会话的 `video_generate` 任务仍处于活动状态时,该工具也会充当防护机制:在同一会话中重复调用 `video_generate`,返回的是活动任务状态,而不是启动第二个并发生成。如果你想从智能体侧显式查询进度 / 状态,请使用 `action: "status"`。
|
||||
当基于会话的 `video_generate` 任务仍处于活动状态时,该工具还会充当保护机制:在同一会话中重复调用 `video_generate` 时,不会启动第二个并发生成,而是返回当前活动任务的状态。当你希望智能体侧明确查询进度/状态时,请使用 `action: "status"`。
|
||||
|
||||
**不会创建任务的情况:**
|
||||
**以下情况不会创建任务:**
|
||||
|
||||
- 心跳轮次——主会话;请参阅[Heartbeat](/zh-CN/gateway/heartbeat)
|
||||
- 心跳轮次 —— 主会话;请参阅 [Heartbeat](/zh-CN/gateway/heartbeat)
|
||||
- 普通交互式聊天轮次
|
||||
- 直接 `/command` 响应
|
||||
|
||||
@ -97,13 +97,13 @@ openclaw tasks flow cancel <lookup>
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> queued
|
||||
queued --> running : agent starts
|
||||
running --> succeeded : completes ok
|
||||
running --> failed : error
|
||||
running --> timed_out : timeout exceeded
|
||||
running --> cancelled : operator cancels
|
||||
queued --> lost : session gone > 5 min
|
||||
running --> lost : session gone > 5 min
|
||||
queued --> running : 智能体启动
|
||||
running --> succeeded : 成功完成
|
||||
running --> failed : 出错
|
||||
running --> timed_out : 超过超时时间
|
||||
running --> cancelled : 操作员取消
|
||||
queued --> lost : 会话消失超过 5 分钟
|
||||
running --> lost : 会话消失超过 5 分钟
|
||||
```
|
||||
|
||||
| 状态 | 含义 |
|
||||
@ -111,45 +111,45 @@ stateDiagram-v2
|
||||
| `queued` | 已创建,等待智能体启动 |
|
||||
| `running` | 智能体轮次正在执行 |
|
||||
| `succeeded` | 已成功完成 |
|
||||
| `failed` | 已因错误完成 |
|
||||
| `timed_out` | 已超出配置的超时时间 |
|
||||
| `cancelled` | 已由操作员通过 `openclaw tasks cancel` 停止 |
|
||||
| `lost` | 运行时在 5 分钟宽限期后失去了权威后端状态 |
|
||||
| `failed` | 因错误而完成 |
|
||||
| `timed_out` | 超过已配置的超时时间 |
|
||||
| `cancelled` | 由操作员通过 `openclaw tasks cancel` 停止 |
|
||||
| `lost` | 在 5 分钟宽限期后,运行时丢失了权威的后备状态 |
|
||||
|
||||
状态转换会自动发生——当关联的智能体运行结束时,任务状态会更新为对应结果。
|
||||
这些状态转换会自动发生 —— 当关联的智能体运行结束时,任务状态会更新为对应结果。
|
||||
|
||||
`lost` 是按运行时感知的:
|
||||
`lost` 是感知运行时类型的:
|
||||
|
||||
- ACP 任务:其后端 ACP 子会话元数据已消失。
|
||||
- 子智能体任务:其后端子会话从目标智能体存储中消失。
|
||||
- Cron 任务:cron 运行时不再将该作业视为活动状态。
|
||||
- CLI 任务:隔离子会话任务使用子会话;基于聊天的 CLI 任务则改用活动运行上下文,因此残留的渠道 / 分组 / 直接会话行不会让它们保持活动。
|
||||
- ACP 任务:后备 ACP 子会话元数据消失。
|
||||
- 子智能体任务:目标智能体存储中的后备子会话消失。
|
||||
- cron 任务:cron 运行时不再将该作业视为活动。
|
||||
- CLI 任务:隔离的子会话任务使用子会话;基于聊天的 CLI 任务则改为使用实时运行上下文,因此残留的渠道/群组/私聊会话行不会让它们继续保持活动。
|
||||
|
||||
## 投递与通知
|
||||
|
||||
当任务进入终态时,OpenClaw 会通知你。有两种投递路径:
|
||||
当任务到达终态时,OpenClaw 会通知你。有两种投递路径:
|
||||
|
||||
**直接投递**——如果任务有渠道目标(`requesterOrigin`),完成消息会直接发送到该渠道(Telegram、Discord、Slack 等)。对于子智能体完成,OpenClaw 还会在可用时保留已绑定的线程 / 话题路由,并且在放弃直接投递之前,可以从请求方会话存储的路由(`lastChannel` / `lastTo` / `lastAccountId`)中补全缺失的 `to` / account。
|
||||
**直接投递** —— 如果任务具有渠道目标(`requesterOrigin`),完成消息会直接发送到该渠道(Telegram、Discord、Slack 等)。对于子智能体完成,OpenClaw 还会在可用时保留已绑定的线程/话题路由,并且在直接投递失败前,可以从请求者会话保存的路由(`lastChannel` / `lastTo` / `lastAccountId`)中补齐缺失的 `to` / account。
|
||||
|
||||
**会话排队投递**——如果直接投递失败,或未设置来源,则更新会作为系统事件排入请求方会话,并在下一次心跳时显示出来。
|
||||
**会话排队投递** —— 如果直接投递失败或未设置 origin,则该更新会作为系统事件排入请求者会话,并在下一次心跳时显示出来。
|
||||
|
||||
<Tip>
|
||||
任务完成会立即触发一次心跳唤醒,因此你可以很快看到结果——无需等待下一次计划中的心跳触发。
|
||||
任务完成会立即触发一次心跳唤醒,因此你能很快看到结果 —— 无需等待下一次计划中的心跳 tick。
|
||||
</Tip>
|
||||
|
||||
这意味着通常的工作流是基于推送的:启动一次分离式工作,然后让运行时在完成时唤醒你或通知你。只有在你需要调试、干预或显式审计时,才去轮询任务状态。
|
||||
这意味着通常的工作流是基于推送的:只需启动一次分离工作,然后让运行时在完成时唤醒或通知你。只有在你需要调试、干预或进行明确审计时,才应轮询任务状态。
|
||||
|
||||
### 通知策略
|
||||
|
||||
控制你希望收到每个任务多少信息:
|
||||
控制你希望收到每个任务多少通知:
|
||||
|
||||
| 策略 | 会投递的内容 |
|
||||
| 策略 | 会投递什么 |
|
||||
| --------------------- | ----------------------------------------------------------------------- |
|
||||
| `done_only`(默认) | 仅终态(succeeded、failed 等)——**这是默认值** |
|
||||
| `state_changes` | 每次状态转换和进度更新 |
|
||||
| `done_only`(默认) | 仅终态(succeeded、failed 等)—— **这是默认值** |
|
||||
| `state_changes` | 每次状态变化和进度更新 |
|
||||
| `silent` | 完全不通知 |
|
||||
|
||||
在任务运行期间更改策略:
|
||||
在任务运行时更改策略:
|
||||
|
||||
```bash
|
||||
openclaw tasks notify <lookup> state_changes
|
||||
@ -163,7 +163,7 @@ openclaw tasks notify <lookup> state_changes
|
||||
openclaw tasks list [--runtime <acp|subagent|cron|cli>] [--status <status>] [--json]
|
||||
```
|
||||
|
||||
输出列:任务 ID、类型、状态、投递、运行 ID、子会话、摘要。
|
||||
输出列:任务 ID、类型、状态、投递、Run ID、子会话、摘要。
|
||||
|
||||
### `tasks show`
|
||||
|
||||
@ -171,7 +171,7 @@ openclaw tasks list [--runtime <acp|subagent|cron|cli>] [--status <status>] [--j
|
||||
openclaw tasks show <lookup>
|
||||
```
|
||||
|
||||
查找标记可接受任务 ID、运行 ID 或会话键。会显示完整记录,包括时间信息、投递状态、错误和终态摘要。
|
||||
lookup 标记支持任务 ID、run ID 或 session key。会显示完整记录,包括时序、投递状态、错误和终态摘要。
|
||||
|
||||
### `tasks cancel`
|
||||
|
||||
@ -179,7 +179,7 @@ openclaw tasks show <lookup>
|
||||
openclaw tasks cancel <lookup>
|
||||
```
|
||||
|
||||
对于 ACP 和子智能体任务,这会终止子会话。对于 CLI 跟踪任务,取消状态会记录到任务注册表中(没有单独的子运行时句柄)。状态会转换为 `cancelled`,并在适用时发送投递通知。
|
||||
对于 ACP 和子智能体任务,这会终止子会话。对于由 CLI 跟踪的任务,取消操作会记录到任务注册表中(没有单独的子运行时句柄)。状态会转换为 `cancelled`,并在适用时发送投递通知。
|
||||
|
||||
### `tasks notify`
|
||||
|
||||
@ -196,13 +196,13 @@ openclaw tasks audit [--json]
|
||||
显示运行问题。检测到问题时,这些发现也会出现在 `openclaw status` 中。
|
||||
|
||||
| 发现项 | 严重级别 | 触发条件 |
|
||||
| ------------------------- | -------- | ----------------------------------------------------- |
|
||||
| `stale_queued` | warn | 排队超过 10 分钟 |
|
||||
| `stale_running` | error | 运行超过 30 分钟 |
|
||||
| `lost` | error | 基于运行时的任务归属状态已消失 |
|
||||
| `delivery_failed` | warn | 投递失败且通知策略不是 `silent` |
|
||||
| ------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `stale_queued` | warn | 处于 queued 超过 10 分钟 |
|
||||
| `stale_running` | error | 处于 running 超过 30 分钟 |
|
||||
| `lost` | warn/error | 运行时支持的任务所有权消失;保留的 lost 任务在 `cleanupAfter` 之前显示为警告,之后升级为错误 |
|
||||
| `delivery_failed` | warn | 投递失败,且通知策略不是 `silent` |
|
||||
| `missing_cleanup` | warn | 终态任务缺少清理时间戳 |
|
||||
| `inconsistent_timestamps` | warn | 时间线违规(例如结束时间早于开始时间) |
|
||||
| `inconsistent_timestamps` | warn | 时间线冲突(例如结束时间早于开始时间) |
|
||||
|
||||
### `tasks maintenance`
|
||||
|
||||
@ -211,21 +211,21 @@ openclaw tasks maintenance [--json]
|
||||
openclaw tasks maintenance --apply [--json]
|
||||
```
|
||||
|
||||
使用此命令可预览或应用针对任务和 Task Flow 状态的对账、清理标记和裁剪操作。
|
||||
用它来预览或应用任务与 Task Flow 状态的对账、清理标记和清除操作。
|
||||
|
||||
对账是按运行时感知的:
|
||||
对账是感知运行时类型的:
|
||||
|
||||
- ACP / 子智能体任务会检查其后端子会话。
|
||||
- Cron 任务会检查 cron 运行时是否仍拥有该作业。
|
||||
- 基于聊天的 CLI 任务会检查所属的活动运行上下文,而不仅仅是聊天会话行。
|
||||
- ACP/子智能体任务会检查其后备子会话。
|
||||
- cron 任务会检查 cron 运行时是否仍然持有该作业。
|
||||
- 基于聊天的 CLI 任务会检查所属的实时运行上下文,而不只是聊天会话行。
|
||||
|
||||
完成清理同样是按运行时感知的:
|
||||
完成清理也同样是感知运行时类型的:
|
||||
|
||||
- 子智能体完成时,会在公告清理继续之前尽力关闭该子会话所跟踪的浏览器标签页 / 进程。
|
||||
- 隔离的 cron 完成时,会在整个运行完全拆除之前尽力关闭 cron 会话所跟踪的浏览器标签页 / 进程。
|
||||
- 隔离的 cron 投递会在需要时等待后代子智能体的后续工作完成,并抑制陈旧的父级确认文本,而不是把它公告出去。
|
||||
- 子智能体完成投递会优先采用最新可见的 assistant 文本;如果为空,则回退为经过净化的最新 tool / toolResult 文本;而仅超时的工具调用运行可以折叠为简短的部分进度摘要。终态为 failed 的运行会公告失败状态,而不会重放已捕获的回复文本。
|
||||
- 清理失败不会掩盖真实的任务结果。
|
||||
- 子智能体完成时,会尽力在继续执行通知清理之前,关闭该子会话已跟踪的浏览器标签页/进程。
|
||||
- 隔离的 cron 完成时,会尽力在运行彻底结束前,关闭该 cron 会话已跟踪的浏览器标签页/进程。
|
||||
- 隔离的 cron 投递会在需要时等待后代子智能体的后续处理结束,并抑制过时的父级确认文本,而不是将其发布出去。
|
||||
- 子智能体完成投递会优先使用最新的可见 assistant 文本;若该文本为空,则回退到已净化的最新 tool/toolResult 文本,而仅包含超时工具调用的运行可能会折叠为简短的部分进度摘要。终态失败的运行会宣告失败状态,而不会重放捕获到的回复文本。
|
||||
- 清理失败不会掩盖任务的真实结果。
|
||||
|
||||
### `tasks flow list|show|cancel`
|
||||
|
||||
@ -235,20 +235,19 @@ openclaw tasks flow show <lookup> [--json]
|
||||
openclaw tasks flow cancel <lookup>
|
||||
```
|
||||
|
||||
当你关心的是编排层面的 Task Flow,而不是某一条单独的后台任务记录时,请使用这些命令。
|
||||
当你关心的是编排中的 Task Flow,而不是某一条单独的后台任务记录时,请使用这些命令。
|
||||
|
||||
## 聊天任务板(`/tasks`)
|
||||
## 聊天任务面板(`/tasks`)
|
||||
|
||||
在任意聊天会话中使用 `/tasks` 可以查看与该会话关联的后台任务。任务板会显示活动中和最近完成的任务,包括运行时、状态、时间信息,以及进度或错误详情。
|
||||
在任何聊天会话中使用 `/tasks` 可查看链接到该会话的后台任务。该面板会显示活动中和最近完成的任务,包括运行时、状态、时序,以及进度或错误详情。
|
||||
|
||||
当当前会话没有可见的关联任务时,`/tasks` 会回退为显示智能体本地任务计数,
|
||||
这样你仍然可以获得概览,而不会泄露其他会话的细节。
|
||||
当当前会话没有可见的已链接任务时,`/tasks` 会回退为显示智能体本地任务计数,这样你仍然可以获得概览,同时不会泄露其他会话的详细信息。
|
||||
|
||||
如需查看完整的操作员账本,请使用 CLI:`openclaw tasks list`。
|
||||
如需查看完整的操作员台账,请使用 CLI:`openclaw tasks list`。
|
||||
|
||||
## 状态集成(任务压力)
|
||||
## Status 集成(任务压力)
|
||||
|
||||
`openclaw status` 包含一个任务概览摘要:
|
||||
`openclaw status` 包含一个可快速查看的任务摘要:
|
||||
|
||||
```
|
||||
Tasks: 3 queued · 2 running · 1 issues
|
||||
@ -260,29 +259,29 @@ Tasks: 3 queued · 2 running · 1 issues
|
||||
- **failures** —— `failed` + `timed_out` + `lost` 的数量
|
||||
- **byRuntime** —— 按 `acp`、`subagent`、`cron`、`cli` 分类的明细
|
||||
|
||||
`/status` 和 `session_status` 工具都会使用带清理感知的任务快照:优先显示活动任务,隐藏过时的已完成记录,并且只有在没有活动工作剩余时才显示最近的失败任务。这让状态卡聚焦于当前真正重要的内容。
|
||||
`/status` 和 `session_status` 工具都会使用感知清理状态的任务快照:优先显示活动任务,隐藏过时的已完成记录,并且仅在没有剩余活动工作时才显示最近失败项。这使状态卡片聚焦于当前最重要的内容。
|
||||
|
||||
## 存储与维护
|
||||
|
||||
### 任务存储位置
|
||||
|
||||
任务记录会持久化到以下 SQLite 路径:
|
||||
任务记录会持久化到 SQLite,路径为:
|
||||
|
||||
```
|
||||
$OPENCLAW_STATE_DIR/tasks/runs.sqlite
|
||||
```
|
||||
|
||||
注册表会在 Gateway 网关启动时加载到内存中,并将写入同步到 SQLite,以确保在重启后仍具备持久性。
|
||||
该注册表会在 Gateway 网关启动时加载到内存中,并将写入同步到 SQLite,以保证重启后的持久性。
|
||||
|
||||
### 自动维护
|
||||
|
||||
清理器每 **60 秒** 运行一次,并处理三件事:
|
||||
清扫器每 **60 秒** 运行一次,并处理三件事:
|
||||
|
||||
1. **对账** —— 检查活动任务是否仍具有权威的运行时后端状态。ACP / 子智能体任务使用子会话状态,cron 任务使用活动作业归属,基于聊天的 CLI 任务使用所属运行上下文。如果该后端状态消失超过 5 分钟,任务会被标记为 `lost`。
|
||||
2. **清理标记** —— 为终态任务设置 `cleanupAfter` 时间戳(`endedAt + 7 days`)。
|
||||
3. **裁剪** —— 删除已超过其 `cleanupAfter` 日期的记录。
|
||||
1. **对账** —— 检查活动任务是否仍然具有权威的运行时后备状态。ACP/子智能体任务使用子会话状态,cron 任务使用活动作业所有权,基于聊天的 CLI 任务使用其所属运行上下文。如果该后备状态消失超过 5 分钟,则任务会被标记为 `lost`。
|
||||
2. **清理标记** —— 为终态任务设置 `cleanupAfter` 时间戳(`endedAt + 7 days`)。在保留期内,`lost` 任务仍会在审计中显示为警告;当 `cleanupAfter` 过期或缺少清理元数据时,它们会变成错误。
|
||||
3. **清除** —— 删除超过 `cleanupAfter` 日期的记录。
|
||||
|
||||
**保留期**:终态任务记录会保留 **7 天**,之后自动清理。无需任何配置。
|
||||
**保留期**:终态任务记录会保留 **7 天**,之后自动清除。无需额外配置。
|
||||
|
||||
## 任务与其他系统的关系
|
||||
|
||||
@ -294,28 +293,28 @@ $OPENCLAW_STATE_DIR/tasks/runs.sqlite
|
||||
|
||||
### 任务与 cron
|
||||
|
||||
cron 作业**定义**存储在 `~/.openclaw/cron/jobs.json`;运行时执行状态存储在旁边的 `~/.openclaw/cron/jobs-state.json`。**每一次** cron 执行都会创建任务记录——主会话和隔离执行都包括在内。主会话 cron 任务默认使用 `silent` 通知策略,因此它们会被跟踪,但不会生成通知。
|
||||
cron 作业的**定义**存储在 `~/.openclaw/cron/jobs.json`;运行时执行状态则存储在其旁边的 `~/.openclaw/cron/jobs-state.json` 中。**每一次** cron 执行都会创建任务记录 —— 无论是主会话还是隔离运行。主会话 cron 任务默认使用 `silent` 通知策略,因此它们会被跟踪,但不会生成通知。
|
||||
|
||||
请参阅 [Cron Jobs](/zh-CN/automation/cron-jobs)。
|
||||
|
||||
### 任务与心跳
|
||||
|
||||
Heartbeat 运行属于主会话轮次——它们不会创建任务记录。当任务完成时,它可以触发一次心跳唤醒,让你及时看到结果。
|
||||
心跳运行属于主会话轮次 —— 它们不会创建任务记录。当任务完成时,它可以触发一次心跳唤醒,以便你及时看到结果。
|
||||
|
||||
请参阅 [Heartbeat](/zh-CN/gateway/heartbeat)。
|
||||
|
||||
### 任务与会话
|
||||
|
||||
任务可能会引用 `childSessionKey`(工作运行的位置)和 `requesterSessionKey`(发起者)。会话是对话上下文;任务则是在其之上的活动跟踪。
|
||||
一个任务可能会引用 `childSessionKey`(工作实际运行的位置)和 `requesterSessionKey`(启动它的是谁)。会话是对话上下文;任务则是在其之上的活动跟踪机制。
|
||||
|
||||
### 任务与智能体运行
|
||||
|
||||
任务的 `runId` 会链接到执行该工作的智能体运行。智能体生命周期事件(开始、结束、错误)会自动更新任务状态——你不需要手动管理生命周期。
|
||||
任务的 `runId` 会链接到执行该工作的智能体运行。智能体生命周期事件(开始、结束、错误)会自动更新任务状态 —— 你无需手动管理生命周期。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [自动化与任务](/zh-CN/automation) —— 一览所有自动化机制
|
||||
- [Automation & Tasks](/zh-CN/automation) —— 所有自动化机制总览
|
||||
- [Task Flow](/zh-CN/automation/taskflow) —— 位于任务之上的流程编排
|
||||
- [计划任务](/zh-CN/automation/cron-jobs) —— 调度后台工作
|
||||
- [Scheduled Tasks](/zh-CN/automation/cron-jobs) —— 调度后台工作
|
||||
- [Heartbeat](/zh-CN/gateway/heartbeat) —— 周期性的主会话轮次
|
||||
- [CLI:任务](/zh-CN/cli/tasks) —— CLI 命令参考
|
||||
- [CLI: Tasks](/zh-CN/cli/tasks) —— CLI 命令参考
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
---
|
||||
read_when:
|
||||
- 处理 WhatsApp / web 渠道行为或收件箱路由
|
||||
- 处理 WhatsApp/web 渠道行为或收件箱路由
|
||||
summary: WhatsApp 渠道支持、访问控制、投递行为和运维
|
||||
title: WhatsApp
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T02:32:11Z"
|
||||
generated_at: "2026-04-26T03:01:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 0e06f394be0e779a65fb1e17b3d4e5d8443c89c93596f4c012bab145dc4904dd
|
||||
source_hash: 120033548f60a39619952e908bd4925dc7da5f8baaa4406ed455aa46010fbb2e
|
||||
source_path: channels/whatsapp.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
Status:通过 WhatsApp Web(Baileys)达到生产就绪。Gateway 网关负责已关联的会话。
|
||||
Status:通过 WhatsApp Web(Baileys)达到生产可用状态。Gateway 网关拥有已关联的会话。
|
||||
|
||||
## 安装(按需)
|
||||
|
||||
- 新手引导(`openclaw onboard`)和 `openclaw channels add --channel whatsapp`
|
||||
会在你第一次选择时提示安装 WhatsApp 插件。
|
||||
- 当插件尚未安装时,`openclaw channels login --channel whatsapp` 也会提供安装流程。
|
||||
- 开发渠道 + git checkout:默认使用本地插件路径。
|
||||
会在你首次选择 WhatsApp 插件时提示安装它。
|
||||
- `openclaw channels login --channel whatsapp` 也会在插件尚未安装时提供安装流程。
|
||||
- 开发渠道 + git 检出:默认使用本地插件路径。
|
||||
- Stable/Beta:默认使用 npm 包 `@openclaw/whatsapp`。
|
||||
|
||||
仍然可以手动安装:
|
||||
也可以继续使用手动安装:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/whatsapp
|
||||
@ -30,10 +30,10 @@ openclaw plugins install @openclaw/whatsapp
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="配对" icon="link" href="/zh-CN/channels/pairing">
|
||||
未知发送者的默认私信策略为配对。
|
||||
未知发件人的默认私信策略是配对。
|
||||
</Card>
|
||||
<Card title="渠道故障排除" icon="wrench" href="/zh-CN/channels/troubleshooting">
|
||||
跨渠道诊断与修复操作手册。
|
||||
跨渠道诊断和修复操作手册。
|
||||
</Card>
|
||||
<Card title="Gateway 网关配置" icon="settings" href="/zh-CN/gateway/configuration">
|
||||
完整的渠道配置模式和示例。
|
||||
@ -72,7 +72,7 @@ openclaw channels login --channel whatsapp
|
||||
openclaw channels login --channel whatsapp --account work
|
||||
```
|
||||
|
||||
如需在登录前附加现有/自定义的 WhatsApp Web 认证目录:
|
||||
要在登录前附加现有/自定义的 WhatsApp Web 认证目录:
|
||||
|
||||
```bash
|
||||
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth
|
||||
@ -81,7 +81,7 @@ openclaw channels login --channel whatsapp --account work
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="启动网关">
|
||||
<Step title="启动 Gateway 网关">
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
@ -89,7 +89,7 @@ openclaw gateway
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="批准第一个配对请求(如果使用配对模式)">
|
||||
<Step title="批准首次配对请求(如果使用配对模式)">
|
||||
|
||||
```bash
|
||||
openclaw pairing list whatsapp
|
||||
@ -102,14 +102,14 @@ openclaw pairing approve whatsapp <CODE>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据和设置流程已针对这种配置进行了优化,但也支持个人号码配置。)
|
||||
OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据和设置流程已针对这种设置优化,但也支持个人号码设置。)
|
||||
</Note>
|
||||
|
||||
## 部署模式
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="专用号码(推荐)">
|
||||
这是最清晰的运维模式:
|
||||
这是最简洁的运维模式:
|
||||
|
||||
- 为 OpenClaw 使用单独的 WhatsApp 身份
|
||||
- 更清晰的私信 allowlist 和路由边界
|
||||
@ -130,19 +130,19 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="个人号码回退方案">
|
||||
<Accordion title="个人号码备用方案">
|
||||
新手引导支持个人号码模式,并会写入适合自聊的基线配置:
|
||||
|
||||
- `dmPolicy: "allowlist"`
|
||||
- `allowFrom` 包含你的个人号码
|
||||
- `selfChatMode: true`
|
||||
|
||||
在运行时,自聊保护会根据已关联的自身号码和 `allowFrom` 生效。
|
||||
在运行时,自聊保护基于已关联的自身号码和 `allowFrom` 生效。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="仅限 WhatsApp Web 的渠道范围">
|
||||
在当前 OpenClaw 渠道架构中,消息平台渠道基于 WhatsApp Web(`Baileys`)。
|
||||
在当前的 OpenClaw 渠道架构中,消息平台渠道基于 WhatsApp Web(`Baileys`)。
|
||||
|
||||
内置聊天渠道注册表中没有单独的 Twilio WhatsApp 消息渠道。
|
||||
|
||||
@ -151,19 +151,19 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据
|
||||
|
||||
## 运行时模型
|
||||
|
||||
- Gateway 网关负责 WhatsApp socket 和重连循环。
|
||||
- 出站发送要求目标账户具有活动中的 WhatsApp 监听器。
|
||||
- Status 和 broadcast 聊天会被忽略(`@status`、`@broadcast`)。
|
||||
- 私聊使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。
|
||||
- 群组会话相互隔离(`agent:<agentId>:whatsapp:group:<jid>`)。
|
||||
- WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` 及其小写变体)。优先使用主机级代理配置,而不是 WhatsApp 渠道专用代理设置。
|
||||
- Gateway 网关拥有 WhatsApp socket 和重连循环。
|
||||
- 出站发送要求目标账户存在活动的 WhatsApp 监听器。
|
||||
- Status 和广播聊天会被忽略(`@status`、`@broadcast`)。
|
||||
- 直接聊天使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。
|
||||
- 群组会话彼此隔离(`agent:<agentId>:whatsapp:group:<jid>`)。
|
||||
- WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` 及其小写变体)。优先使用主机级代理配置,而不是渠道专用的 WhatsApp 代理设置。
|
||||
|
||||
## 插件钩子与隐私
|
||||
|
||||
WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
群组标识符、发送者名称以及会话关联字段。因此,
|
||||
除非你显式选择加入,否则 WhatsApp 不会向插件广播入站
|
||||
`message_received` hook 载荷:
|
||||
群组标识符、发件人姓名以及会话关联字段。因此,
|
||||
除非你明确选择启用,否则 WhatsApp 不会向插件广播入站
|
||||
`message_received` hook 负载:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -177,7 +177,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
}
|
||||
```
|
||||
|
||||
你也可以将此选择加入限定到某一个账户:
|
||||
你也可以将此选择启用范围限制到单个账户:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -195,49 +195,50 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
}
|
||||
```
|
||||
|
||||
仅在你信任插件可以接收入站 WhatsApp 消息内容和标识符时,才启用此功能。
|
||||
仅当你信任插件可以接收入站 WhatsApp 消息内容和标识符时,
|
||||
才启用此功能。
|
||||
|
||||
## 访问控制与激活
|
||||
|
||||
<Tabs>
|
||||
<Tab title="私信策略">
|
||||
`channels.whatsapp.dmPolicy` 控制私聊访问:
|
||||
`channels.whatsapp.dmPolicy` 控制直接聊天访问:
|
||||
|
||||
- `pairing`(默认)
|
||||
- `allowlist`
|
||||
- `open`(要求 `allowFrom` 包含 `"*"`)
|
||||
- `disabled`
|
||||
|
||||
`allowFrom` 接受 E.164 风格的号码(内部会规范化)。
|
||||
`allowFrom` 接受 E.164 风格的号码(内部会进行规范化)。
|
||||
|
||||
多账户覆盖:对于该账户,`channels.whatsapp.accounts.<id>.dmPolicy`(以及 `allowFrom`)优先于渠道级默认值。
|
||||
|
||||
运行时行为细节:
|
||||
|
||||
- 配对会持久化到渠道 allow-store 中,并与已配置的 `allowFrom` 合并
|
||||
- 如果未配置任何 allowlist,则默认允许已关联的自身号码
|
||||
- OpenClaw 绝不会自动配对出站 `fromMe` 私信(即你从已关联设备发送给自己的消息)
|
||||
- 配对会持久化到渠道 allow-store,并与已配置的 `allowFrom` 合并
|
||||
- 如果未配置 allowlist,默认允许已关联的自身号码
|
||||
- OpenClaw 绝不会自动配对出站 `fromMe` 私信(即你从已关联设备发给自己的消息)
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="群组策略 + allowlist">
|
||||
群组访问有两层:
|
||||
群组访问分为两层:
|
||||
|
||||
1. **群组成员资格 allowlist**(`channels.whatsapp.groups`)
|
||||
1. **群组成员 allowlist**(`channels.whatsapp.groups`)
|
||||
- 如果省略 `groups`,则所有群组都有资格
|
||||
- 如果存在 `groups`,它会作为群组 allowlist(允许 `"*"`)
|
||||
|
||||
2. **群组发送者策略**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
|
||||
- `open`:绕过发送者 allowlist
|
||||
- `allowlist`:发送者必须匹配 `groupAllowFrom`(或 `*`)
|
||||
2. **群组发件人策略**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`)
|
||||
- `open`:绕过发件人 allowlist
|
||||
- `allowlist`:发件人必须匹配 `groupAllowFrom`(或 `*`)
|
||||
- `disabled`:阻止所有群组入站消息
|
||||
|
||||
发送者 allowlist 回退:
|
||||
发件人 allowlist 回退:
|
||||
|
||||
- 如果未设置 `groupAllowFrom`,运行时会在可用时回退到 `allowFrom`
|
||||
- 发送者 allowlist 会在提及/回复激活之前进行评估
|
||||
- 发件人 allowlist 会在提及/回复激活之前进行评估
|
||||
|
||||
注意:如果根本不存在 `channels.whatsapp` 配置块,则运行时的群组策略回退为 `allowlist`(并带有警告日志),即使设置了 `channels.defaults.groupPolicy` 也是如此。
|
||||
注意:如果根本不存在 `channels.whatsapp` 配置块,运行时的群组策略回退为 `allowlist`(并记录警告日志),即使设置了 `channels.defaults.groupPolicy` 也是如此。
|
||||
|
||||
</Tab>
|
||||
|
||||
@ -247,39 +248,39 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
提及检测包括:
|
||||
|
||||
- 对机器人身份的显式 WhatsApp 提及
|
||||
- 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退为 `messages.groupChat.mentionPatterns`)
|
||||
- 隐式回复机器人检测(回复发送者与机器人身份匹配)
|
||||
- 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`)
|
||||
- 隐式回复机器人的检测(回复发送者匹配机器人身份)
|
||||
|
||||
安全说明:
|
||||
|
||||
- 引用/回复只满足提及门控;它**不会**授予发送者授权
|
||||
- 使用 `groupPolicy: "allowlist"` 时,即使非 allowlist 发送者回复了 allowlist 用户的消息,也仍会被阻止
|
||||
- 引用/回复仅满足提及门控;它**不会**授予发件人授权
|
||||
- 当 `groupPolicy: "allowlist"` 时,即使非 allowlist 发件人回复了 allowlist 用户的消息,仍会被阻止
|
||||
|
||||
会话级激活命令:
|
||||
|
||||
- `/activation mention`
|
||||
- `/activation always`
|
||||
|
||||
`activation` 会更新会话状态(不是全局配置)。它受 owner 权限控制。
|
||||
`activation` 会更新会话状态(而非全局配置)。它受所有者权限控制。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 个人号码与自聊行为
|
||||
|
||||
当已关联的自身号码也出现在 `allowFrom` 中时,会启用 WhatsApp 自聊保护:
|
||||
当已关联的自身号码同时存在于 `allowFrom` 中时,WhatsApp 自聊保护会启用:
|
||||
|
||||
- 跳过自聊轮次的已读回执
|
||||
- 忽略原本会提醒你自己的 mention-JID 自动触发行为
|
||||
- 跳过自聊回合的已读回执
|
||||
- 忽略原本会触发给自己发送提醒的 mention-JID 自动触发行为
|
||||
- 如果未设置 `messages.responsePrefix`,自聊回复默认使用 `[{identity.name}]` 或 `[openclaw]`
|
||||
|
||||
## 消息规范化与上下文
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="入站信封 + 回复上下文">
|
||||
传入的 WhatsApp 消息会被包装进共享的入站信封中。
|
||||
传入的 WhatsApp 消息会被包装到共享的入站信封中。
|
||||
|
||||
如果存在引用回复,上下文会按以下形式附加:
|
||||
如果存在引用回复,上下文会以如下形式追加:
|
||||
|
||||
```text
|
||||
[Replying to <sender> id:<stanzaId>]
|
||||
@ -287,12 +288,12 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
[/Replying]
|
||||
```
|
||||
|
||||
在可用时,也会填充回复元数据字段(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发送者 JID/E.164)。
|
||||
回复元数据字段也会在可用时填充(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发件人 JID/E.164)。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="媒体占位符与位置/联系人提取">
|
||||
仅含媒体的入站消息会使用如下占位符进行规范化:
|
||||
<Accordion title="媒体占位符以及位置/联系人提取">
|
||||
仅含媒体的入站消息会被规范化为如下占位符:
|
||||
|
||||
- `<media:image>`
|
||||
- `<media:video>`
|
||||
@ -300,14 +301,14 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
- `<media:document>`
|
||||
- `<media:sticker>`
|
||||
|
||||
位置正文使用简洁的坐标文本。位置标签/备注以及联系人/vCard 详情会渲染为带围栏的不可信元数据,而不是内联提示文本。
|
||||
位置消息正文使用简洁的坐标文本。位置标签/备注以及联系人/vCard 详情会渲染为带围栏的不受信任元数据,而不是内联提示文本。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="待处理群组历史注入">
|
||||
对于群组,当机器人最终被触发时,未处理的消息可以被缓冲并作为上下文注入。
|
||||
对于群组,当机器人最终被触发时,未处理消息可以被缓冲并作为上下文注入。
|
||||
|
||||
- 默认限制:`50`
|
||||
- 默认上限:`50`
|
||||
- 配置:`channels.whatsapp.historyLimit`
|
||||
- 回退:`messages.groupChat.historyLimit`
|
||||
- `0` 表示禁用
|
||||
@ -320,7 +321,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="已读回执">
|
||||
默认会为已接受的入站 WhatsApp 消息启用已读回执。
|
||||
默认会为已接受的入站 WhatsApp 消息发送已读回执。
|
||||
|
||||
全局禁用:
|
||||
|
||||
@ -350,28 +351,29 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
}
|
||||
```
|
||||
|
||||
即使全局启用,自聊轮次也会跳过已读回执。
|
||||
即使全局启用,自聊回合也会跳过已读回执。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 投递、分块与媒体
|
||||
## 投递、分块和媒体
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="文本分块">
|
||||
- 默认分块上限:`channels.whatsapp.textChunkLimit = 4000`
|
||||
- `channels.whatsapp.chunkMode = "length" | "newline"`
|
||||
- `newline` 模式优先按段落边界(空行)分块,然后回退到按长度安全分块
|
||||
- `newline` 模式优先按段落边界(空行)切分,然后再回退到按长度安全分块
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="出站媒体行为">
|
||||
- 支持图片、视频、音频(PTT 语音便笺)和文档载荷
|
||||
- 音频媒体通过 Baileys 的 `audio` 载荷并设置 `ptt: true` 发送,因此 WhatsApp 客户端会将其渲染为按住说话语音便笺
|
||||
- 回复载荷会保留 `audioAsVoice`;即使提供商返回 MP3 或 WebM,WhatsApp 的 TTS 语音便笺输出也会继续走此 PTT 路径
|
||||
- 支持图片、视频、音频(PTT 语音便笺)和文档负载
|
||||
- 音频媒体通过 Baileys 的 `audio` 负载发送,并设置 `ptt: true`,因此 WhatsApp 客户端会将其渲染为按住说话语音便笺
|
||||
- 回复负载会保留 `audioAsVoice`;WhatsApp 的 TTS 语音便笺输出即使提供商返回的是 MP3 或 WebM,也会继续走这个 PTT 路径
|
||||
- 原生 Ogg/Opus 音频会以 `audio/ogg; codecs=opus` 发送,以兼容语音便笺
|
||||
- 非 Ogg 音频(包括 Microsoft Edge TTS 的 MP3/WebM 输出)会在 PTT 投递前通过 `ffmpeg` 转码为 48 kHz 单声道 Ogg/Opus
|
||||
- 发送视频时通过 `gifPlayback: true` 支持动画 GIF 播放
|
||||
- 发送多媒体回复载荷时,说明文字会应用到第一项媒体;但 PTT 语音便笺会先发送音频,再单独发送可见文本,因为 WhatsApp 客户端对语音便笺说明文字的渲染并不一致
|
||||
- `/tts latest` 会将最近一次助手回复作为单条语音便笺发送,并抑制对同一回复的重复发送;`/tts chat on|off|default` 控制当前 WhatsApp 聊天的自动 TTS
|
||||
- 发送视频时支持通过 `gifPlayback: true` 播放动图 GIF
|
||||
- 发送多媒体回复负载时,说明文字会应用到第一项媒体;但 PTT 语音便笺会先发送音频,再单独发送可见文本,因为 WhatsApp 客户端对语音便笺说明文字的渲染并不一致
|
||||
- 媒体来源可以是 HTTP(S)、`file://` 或本地路径
|
||||
</Accordion>
|
||||
|
||||
@ -379,21 +381,21 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、
|
||||
- 入站媒体保存上限:`channels.whatsapp.mediaMaxMb`(默认 `50`)
|
||||
- 出站媒体发送上限:`channels.whatsapp.mediaMaxMb`(默认 `50`)
|
||||
- 按账户覆盖使用 `channels.whatsapp.accounts.<accountId>.mediaMaxMb`
|
||||
- 图片会自动优化(调整尺寸/质量扫描)以适配限制
|
||||
- 图片会自动优化(尺寸/质量扫描)以适配限制
|
||||
- 媒体发送失败时,首项回退会发送文本警告,而不是静默丢弃响应
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 回复引用
|
||||
|
||||
WhatsApp 支持原生回复引用,出站回复会可见地引用入站消息。使用 `channels.whatsapp.replyToMode` 进行控制。
|
||||
WhatsApp 支持原生回复引用,即出站回复会以可见方式引用入站消息。可通过 `channels.whatsapp.replyToMode` 控制。
|
||||
|
||||
| 值 | 行为 |
|
||||
| ----------- | --------------------------------------------------------------------- |
|
||||
| `"off"` | 从不引用;作为普通消息发送 |
|
||||
| `"first"` | 仅引用第一段出站回复分块 |
|
||||
| `"all"` | 引用每一段出站回复分块 |
|
||||
| `"batched"` | 引用排队的批量回复,同时让即时回复不带引用 |
|
||||
| `"off"` | 从不引用;作为普通消息发送 |
|
||||
| `"first"` | 仅引用第一段出站回复分块 |
|
||||
| `"all"` | 引用每一段出站回复分块 |
|
||||
| `"batched"` | 引用排队的批量回复,同时保持即时回复不引用 |
|
||||
|
||||
默认值为 `"off"`。按账户覆盖使用 `channels.whatsapp.accounts.<id>.replyToMode`。
|
||||
|
||||
@ -409,14 +411,14 @@ WhatsApp 支持原生回复引用,出站回复会可见地引用入站消息
|
||||
|
||||
## Reaction 级别
|
||||
|
||||
`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用 emoji reaction 的广泛程度:
|
||||
`channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用表情 प्रतिक्रिया的范围:
|
||||
|
||||
| 级别 | 确认 reaction | 智能体主动 reaction | 说明 |
|
||||
| 级别 | 确认反应 | 智能体主动反应 | 描述 |
|
||||
| ------------- | ------------- | ------------------------- | ------------------------------------------------ |
|
||||
| `"off"` | 否 | 否 | 完全不使用 reaction |
|
||||
| `"ack"` | 是 | 否 | 仅确认 reaction(回复前确认收到) |
|
||||
| `"minimal"` | 是 | 是(保守) | 确认 + 智能体 reaction,并采用保守指导 |
|
||||
| `"extensive"` | 是 | 是(鼓励) | 确认 + 智能体 reaction,并采用鼓励式指导 |
|
||||
| `"off"` | 否 | 否 | 完全不使用反应 |
|
||||
| `"ack"` | 是 | 否 | 仅确认反应(回复前回执) |
|
||||
| `"minimal"` | 是 | 是(保守) | 确认反应 + 带保守指导的智能体反应 |
|
||||
| `"extensive"` | 是 | 是(鼓励) | 确认反应 + 带鼓励指导的智能体反应 |
|
||||
|
||||
默认值:`"minimal"`。
|
||||
|
||||
@ -432,10 +434,10 @@ WhatsApp 支持原生回复引用,出站回复会可见地引用入站消息
|
||||
}
|
||||
```
|
||||
|
||||
## 确认 reaction
|
||||
## 确认反应
|
||||
|
||||
WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时立即发送确认 reaction。
|
||||
确认 reaction 受 `reactionLevel` 控制 —— 当 `reactionLevel` 为 `"off"` 时会被抑制。
|
||||
WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时立即发送确认反应。
|
||||
确认反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会被抑制。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -453,9 +455,9 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时
|
||||
|
||||
行为说明:
|
||||
|
||||
- 在接受入站消息后立即发送(回复前)
|
||||
- 失败会记录日志,但不会阻塞正常回复投递
|
||||
- 群组模式 `mentions` 会在由提及触发的轮次发送 reaction;群组激活 `always` 会绕过此检查
|
||||
- 在入站消息被接受后立即发送(回复前)
|
||||
- 失败会被记录日志,但不会阻止正常回复投递
|
||||
- 群组模式 `mentions` 会在由提及触发的回合发送反应;群组激活 `always` 可绕过此检查
|
||||
- WhatsApp 使用 `channels.whatsapp.ackReaction`(此处不使用旧版 `messages.ackReaction`)
|
||||
|
||||
## 多账户与凭证
|
||||
@ -463,8 +465,8 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时
|
||||
<AccordionGroup>
|
||||
<Accordion title="账户选择与默认值">
|
||||
- 账户 id 来自 `channels.whatsapp.accounts`
|
||||
- 默认账户选择:如果存在则为 `default`,否则为第一个已配置的账户 id(已排序)
|
||||
- 账户 id 会在内部规范化后用于查找
|
||||
- 默认账户选择:如果存在 `default` 则使用它,否则使用第一个已配置的账户 id(排序后)
|
||||
- 账户 id 会在内部规范化以供查找
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="凭证路径与旧版兼容性">
|
||||
@ -476,15 +478,15 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时
|
||||
<Accordion title="登出行为">
|
||||
`openclaw channels logout --channel whatsapp [--account <id>]` 会清除该账户的 WhatsApp 认证状态。
|
||||
|
||||
在旧版认证目录中,会保留 `oauth.json`,同时删除 Baileys 认证文件。
|
||||
在旧版认证目录中,会保留 `oauth.json`,同时移除 Baileys 认证文件。
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 工具、动作与配置写入
|
||||
## 工具、操作与配置写入
|
||||
|
||||
- 智能体工具支持包括 WhatsApp reaction 动作(`react`)。
|
||||
- 动作门控:
|
||||
- 智能体工具支持包括 WhatsApp reaction 操作(`react`)。
|
||||
- 操作门控:
|
||||
- `channels.whatsapp.actions.reactions`
|
||||
- `channels.whatsapp.actions.polls`
|
||||
- 默认启用由渠道发起的配置写入(可通过 `channels.whatsapp.configWrites=false` 禁用)。
|
||||
@ -493,9 +495,9 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="未关联(需要 QR)">
|
||||
症状:渠道状态显示未关联。
|
||||
症状:渠道 Status 报告未关联。
|
||||
|
||||
修复:
|
||||
修复方法:
|
||||
|
||||
```bash
|
||||
openclaw channels login --channel whatsapp
|
||||
@ -505,9 +507,9 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="已关联但已断开 / 重连循环">
|
||||
症状:已关联账户反复断开或重复尝试重连。
|
||||
症状:已关联账户反复断开或尝试重连。
|
||||
|
||||
修复:
|
||||
修复方法:
|
||||
|
||||
```bash
|
||||
openclaw doctor
|
||||
@ -519,14 +521,14 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="发送时没有活动监听器">
|
||||
当目标账户不存在活动中的 Gateway 网关监听器时,出站发送会快速失败。
|
||||
当目标账户不存在活动的 Gateway 网关监听器时,出站发送会快速失败。
|
||||
|
||||
请确保 Gateway 网关正在运行,并且该账户已关联。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="群组消息被意外忽略">
|
||||
请按以下顺序检查:
|
||||
<Accordion title="群组消息意外被忽略">
|
||||
按以下顺序检查:
|
||||
|
||||
- `groupPolicy`
|
||||
- `groupAllowFrom` / `allowFrom`
|
||||
@ -537,38 +539,38 @@ WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Bun 运行时警告">
|
||||
WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为不兼容稳定的 WhatsApp / Telegram Gateway 网关运行。
|
||||
WhatsApp Gateway 网关运行时应使用 Node。Bun 被标记为不兼容稳定的 WhatsApp/Telegram Gateway 网关运行。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 系统提示词
|
||||
|
||||
WhatsApp 通过 `groups` 和 `direct` 映射支持类似 Telegram 的群组和私聊系统提示词。
|
||||
WhatsApp 支持类似 Telegram 的群组和直接聊天系统提示词,通过 `groups` 和 `direct` 映射实现。
|
||||
|
||||
群组消息的解析层级:
|
||||
|
||||
首先确定生效的 `groups` 映射:如果账户定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不进行深度合并)。随后提示词查找会在得到的这个单一映射上进行:
|
||||
首先确定生效的 `groups` 映射:如果账户定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不进行深度合并)。随后提示词查找会在得到的单一映射上进行:
|
||||
|
||||
1. **群组专用系统提示词**(`groups["<groupId>"].systemPrompt`):当映射中存在该特定群组条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,并且不应用任何系统提示词。
|
||||
1. **群组专属系统提示词**(`groups["<groupId>"].systemPrompt`):当映射中存在该特定群组条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,不应用任何系统提示词。
|
||||
2. **群组通配符系统提示词**(`groups["*"].systemPrompt`):当映射中完全不存在该特定群组条目,或者该条目存在但未定义 `systemPrompt` 键时使用。
|
||||
|
||||
私聊消息的解析层级:
|
||||
直接消息的解析层级:
|
||||
|
||||
首先确定生效的 `direct` 映射:如果账户定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不进行深度合并)。随后提示词查找会在得到的这个单一映射上进行:
|
||||
首先确定生效的 `direct` 映射:如果账户定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不进行深度合并)。随后提示词查找会在得到的单一映射上进行:
|
||||
|
||||
1. **私聊专用系统提示词**(`direct["<peerId>"].systemPrompt`):当映射中存在该特定对端条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,并且不应用任何系统提示词。
|
||||
2. **私聊通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在该特定对端条目,或者该条目存在但未定义 `systemPrompt` 键时使用。
|
||||
1. **直接消息专属系统提示词**(`direct["<peerId>"].systemPrompt`):当映射中存在该特定对端条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,不应用任何系统提示词。
|
||||
2. **直接消息通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在该特定对端条目,或者该条目存在但未定义 `systemPrompt` 键时使用。
|
||||
|
||||
注意:`dms` 仍然是轻量级的按私信历史覆盖桶(`dms.<id>.historyLimit`);提示词覆盖位于 `direct` 下。
|
||||
|
||||
**与 Telegram 多账户行为的区别:** 在 Telegram 中,在多账户设置下,根级 `groups` 会被有意地对所有账户抑制——即使某些账户根本没有定义自己的 `groups` 也是如此——以防止机器人接收其并未加入的群组消息。WhatsApp 不应用这一保护:对于未定义账户级覆盖的账户,无论配置了多少个账户,都会始终继承根级 `groups` 和根级 `direct`。在多账户 WhatsApp 设置中,如果你希望按账户设置群组或私聊提示词,请在每个账户下显式定义完整映射,而不要依赖根级默认值。
|
||||
**与 Telegram 多账户行为的区别:** 在 Telegram 中,在多账户设置里,根级 `groups` 会被有意地对所有账户抑制——即便那些账户没有定义自己的 `groups`——以防机器人接收到其并不属于的群组消息。WhatsApp 不应用这项保护:无论配置了多少个账户,对于未定义账户级覆盖的账户,根级 `groups` 和根级 `direct` 都始终会被继承。在多账户 WhatsApp 设置中,如果你希望为每个账户设置群组或直接消息提示词,请在每个账户下显式定义完整映射,而不是依赖根级默认值。
|
||||
|
||||
重要行为:
|
||||
|
||||
- `channels.whatsapp.groups` 既是按群组配置映射,也是聊天级群组 allowlist。在根级或账户作用域下,`groups["*"]` 都表示“该作用域下允许所有群组进入”。
|
||||
- 只有当你本来就希望该作用域允许所有群组进入时,才添加通配符群组 `systemPrompt`。如果你仍然只希望固定的一组群组 id 有资格进入,请不要将 `groups["*"]` 用作提示词默认值。相反,请在每个显式加入 allowlist 的群组条目中重复该提示词。
|
||||
- 群组准入和发送者授权是分开的检查。`groups["*"]` 会扩大可以进入群组处理的群组集合,但它本身不会授权这些群组中的每个发送者。发送者访问仍然由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。
|
||||
- `channels.whatsapp.direct` 对私信没有相同的副作用。`direct["*"]` 仅在私信已经通过 `dmPolicy` 加上 `allowFrom` 或配对存储规则获准后,提供默认私聊配置。
|
||||
- `channels.whatsapp.groups` 同时是按群组的配置映射和聊天级群组 allowlist。在根级或账户级作用域中,`groups["*"]` 表示该作用域“允许所有群组”。
|
||||
- 只有在你本来就希望该作用域允许所有群组时,才添加通配符群组 `systemPrompt`。如果你仍然只希望固定的一组群组 id 有资格使用,不要将 `groups["*"]` 用作提示词默认值。相反,应在每个明确加入 allowlist 的群组条目上重复填写该提示词。
|
||||
- 群组准入和发件人授权是两个独立检查。`groups["*"]` 会扩大可以进入群组处理流程的群组集合,但它本身不会授权这些群组中的每一个发件人。发件人访问仍然由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。
|
||||
- `channels.whatsapp.direct` 对私信没有相同的副作用。`direct["*"]` 仅在私信已经通过 `dmPolicy` 加上 `allowFrom` 或配对存储规则被允许之后,提供默认的直接聊天配置。
|
||||
|
||||
示例:
|
||||
|
||||
@ -577,31 +579,31 @@ WhatsApp 通过 `groups` 和 `direct` 映射支持类似 Telegram 的群组和
|
||||
channels: {
|
||||
whatsapp: {
|
||||
groups: {
|
||||
// 仅当根级作用域应允许所有群组进入时使用。
|
||||
// 适用于所有未定义自己 groups 映射的账户。
|
||||
"*": { systemPrompt: "所有群组的默认提示词。" },
|
||||
// Only use if all groups should be admitted at the root scope.
|
||||
// Applies to all accounts that do not define their own groups map.
|
||||
"*": { systemPrompt: "Default prompt for all groups." },
|
||||
},
|
||||
direct: {
|
||||
// 适用于所有未定义自己 direct 映射的账户。
|
||||
"*": { systemPrompt: "所有私聊的默认提示词。" },
|
||||
// Applies to all accounts that do not define their own direct map.
|
||||
"*": { systemPrompt: "Default prompt for all direct chats." },
|
||||
},
|
||||
accounts: {
|
||||
work: {
|
||||
groups: {
|
||||
// 该账户定义了自己的 groups,因此根级 groups 会被完全
|
||||
// 替换。若要保留通配符,也需要在这里显式定义 "*"。
|
||||
// This account defines its own groups, so root groups are fully
|
||||
// replaced. To keep a wildcard, define "*" explicitly here too.
|
||||
"120363406415684625@g.us": {
|
||||
requireMention: false,
|
||||
systemPrompt: "聚焦项目管理。",
|
||||
systemPrompt: "Focus on project management.",
|
||||
},
|
||||
// 仅当该账户中应允许所有群组进入时使用。
|
||||
"*": { systemPrompt: "工作群组的默认提示词。" },
|
||||
// Use only if all groups should be admitted in this account.
|
||||
"*": { systemPrompt: "Default prompt for work groups." },
|
||||
},
|
||||
direct: {
|
||||
// 该账户定义了自己的 direct 映射,因此根级 direct 条目会被
|
||||
// 完全替换。若要保留通配符,也需要在这里显式定义 "*"。
|
||||
"+15551234567": { systemPrompt: "特定工作私聊的提示词。" },
|
||||
"*": { systemPrompt: "工作私聊的默认提示词。" },
|
||||
// This account defines its own direct map, so root direct entries are
|
||||
// fully replaced. To keep a wildcard, define "*" explicitly here too.
|
||||
"+15551234567": { systemPrompt: "Prompt for a specific work direct chat." },
|
||||
"*": { systemPrompt: "Default prompt for work direct chats." },
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -610,7 +612,7 @@ WhatsApp 通过 `groups` 和 `direct` 映射支持类似 Telegram 的群组和
|
||||
}
|
||||
```
|
||||
|
||||
## 配置参考指引
|
||||
## 配置参考指针
|
||||
|
||||
主要参考:
|
||||
|
||||
|
||||
@ -1,22 +1,22 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想检查、审计或取消后台任务记录
|
||||
- 你正在为 `openclaw tasks flow` 下的 Task Flow 命令编写文档
|
||||
summary: '`openclaw tasks` 的 CLI 参考(后台任务账本和 Task Flow 状态)'
|
||||
- 你想要检查、审计或取消后台任务记录
|
||||
- 你正在记录 `openclaw tasks flow` 下的 Task Flow 命令
|
||||
summary: '`openclaw tasks` 的 CLI 参考(后台任务分类账和 Task Flow 状态)'
|
||||
title: '`openclaw tasks`'
|
||||
x-i18n:
|
||||
generated_at: "2026-04-24T04:01:38Z"
|
||||
generated_at: "2026-04-26T03:01:23Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 55aab29821578bf8c09e1b6cd5bbeb5e3dae4438e453b418fa7e8420412c8152
|
||||
source_hash: e87f64c2e41704b73cac60924be0f52dad9addec29d543cf5bab06c3045761a0
|
||||
source_path: cli/tasks.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
检查持久化后台任务和 Task Flow 状态。不带子命令时,
|
||||
检查持久化后台任务和 Task Flow 状态。若不带子命令,
|
||||
`openclaw tasks` 等同于 `openclaw tasks list`。
|
||||
|
||||
有关生命周期和投递模型,请参阅 [后台任务](/zh-CN/automation/tasks)。
|
||||
有关生命周期和传递模型,请参阅 [后台任务](/zh-CN/automation/tasks)。
|
||||
|
||||
## 用法
|
||||
|
||||
@ -58,7 +58,7 @@ openclaw tasks list [--runtime <name>] [--status <name>] [--json]
|
||||
openclaw tasks show <lookup> [--json]
|
||||
```
|
||||
|
||||
按任务 ID、运行 ID 或会话键显示单个任务。
|
||||
通过任务 ID、运行 ID 或会话键显示单个任务。
|
||||
|
||||
### `notify`
|
||||
|
||||
@ -82,7 +82,7 @@ openclaw tasks cancel <lookup>
|
||||
openclaw tasks audit [--severity <warn|error>] [--code <name>] [--limit <n>] [--json]
|
||||
```
|
||||
|
||||
显示陈旧、丢失、投递失败或其他不一致的任务和 Task Flow 记录。
|
||||
显示陈旧、丢失、传递失败或其他不一致的任务和 Task Flow 记录。保留到 `cleanupAfter` 的丢失任务属于警告;已过期或未加时间戳的丢失任务属于错误。
|
||||
|
||||
### `maintenance`
|
||||
|
||||
@ -90,7 +90,7 @@ openclaw tasks audit [--severity <warn|error>] [--code <name>] [--limit <n>] [--
|
||||
openclaw tasks maintenance [--apply] [--json]
|
||||
```
|
||||
|
||||
预览或应用任务和 Task Flow 对账、清理标记以及修剪。
|
||||
预览或应用任务和 Task Flow 对账、清理时间戳标记以及修剪。
|
||||
|
||||
### `flow`
|
||||
|
||||
@ -100,9 +100,9 @@ openclaw tasks flow show <lookup> [--json]
|
||||
openclaw tasks flow cancel <lookup>
|
||||
```
|
||||
|
||||
检查或取消任务账本下的持久化 Task Flow 状态。
|
||||
检查或取消任务分类账下持久化的 Task Flow 状态。
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [CLI 参考](/zh-CN/cli)
|
||||
- [后台任务](/zh-CN/automation/tasks)
|
||||
|
||||
@ -1,59 +1,59 @@
|
||||
---
|
||||
read_when:
|
||||
- 你需要一份按提供商逐项说明的模型设置参考。
|
||||
- 你想要模型提供商的示例配置或 CLI 新手引导命令。
|
||||
- 你需要一份按提供商划分的模型设置参考文档
|
||||
- 你想要模型提供商的示例配置或 CLI 新手引导命令
|
||||
summary: 模型提供商概览,附示例配置 + CLI 流程
|
||||
title: 模型提供商
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T17:30:19Z"
|
||||
generated_at: "2026-04-26T03:01:21Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 0991f256bfeda9086eaa2911cc8056561dce84ee8cb9c16e99602eb396bbee83
|
||||
source_hash: 75d0e89c35d46b0c3ecd4a180ca25bb1cdf45cee8dd09d73657517927e7bc220
|
||||
source_path: concepts/model-providers.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
**LLM/模型提供商** 参考(不是像 WhatsApp/Telegram 这样的聊天渠道)。关于模型选择规则,请参阅 [Models](/zh-CN/concepts/models)。
|
||||
**LLM/模型提供商** 参考文档(不是像 WhatsApp/Telegram 这样的聊天渠道)。关于模型选择规则,请参见 [Models](/zh-CN/concepts/models)。
|
||||
|
||||
## 快速规则
|
||||
|
||||
- 模型引用使用 `provider/model`(示例:`opencode/claude-opus-4-6`)。
|
||||
- 设置后,`agents.defaults.models` 会作为允许列表。
|
||||
- CLI 辅助命令:`openclaw onboard`、`openclaw models list`、`openclaw models set <provider/model>`。
|
||||
- 设置后,`agents.defaults.models` 会充当允许列表。
|
||||
- CLI 助手:`openclaw onboard`、`openclaw models list`、`openclaw models set <provider/model>`。
|
||||
- `models.providers.*.models[].contextWindow` 是原生模型元数据;`contextTokens` 是运行时生效的上限。
|
||||
- 回退规则、冷却探测和会话覆盖持久化:参见 [模型故障切换](/zh-CN/concepts/model-failover)。
|
||||
- OpenAI 系列路由是按前缀区分的:`openai/<model>` 使用 PI 中直连 OpenAI API 密钥提供商,`openai-codex/<model>` 使用 PI 中的 Codex OAuth,而 `openai/<model>` 加上 `agents.defaults.embeddedHarness.runtime: "codex"` 则使用原生 Codex 应用服务器 Codex harness。参见 [OpenAI](/zh-CN/providers/openai) 和 [Codex harness](/zh-CN/plugins/codex-harness)。如果你对提供商/运行时的拆分感到困惑,请先阅读 [Agent Runtimes](/zh-CN/concepts/agent-runtimes)。
|
||||
- 插件自动启用也遵循同样的边界:`openai-codex/<model>` 属于 OpenAI 插件,而 Codex 插件由 `embeddedHarness.runtime: "codex"` 或旧版 `codex/<model>` 引用启用。
|
||||
- CLI 运行时也使用同样的拆分:选择规范模型引用,例如 `anthropic/claude-*`、`google/gemini-*` 或 `openai/gpt-*`,然后在你希望使用本地 CLI 后端时,将 `agents.defaults.embeddedHarness.runtime` 设置为 `claude-cli`、`google-gemini-cli` 或 `codex-cli`。旧版 `claude-cli/*`、`google-gemini-cli/*` 和 `codex-cli/*` 引用会迁移回规范提供商引用,并将运行时单独记录。
|
||||
- GPT-5.5 可通过 `openai/gpt-5.5` 用于直接 API 密钥流量,通过 PI 中的 `openai-codex/gpt-5.5` 用于 Codex OAuth,以及在设置 `embeddedHarness.runtime: "codex"` 时通过原生 Codex 应用服务器 Codex harness 使用。
|
||||
- 回退规则、冷却探测和会话覆盖持久化: [模型故障切换](/zh-CN/concepts/model-failover)。
|
||||
- OpenAI 系列路由按前缀区分:`openai/<model>` 在 PI 中使用直接的 OpenAI API 密钥提供商,`openai-codex/<model>` 在 PI 中使用 Codex OAuth,而 `openai/<model>` 加上 `agents.defaults.embeddedHarness.runtime: "codex"` 则使用原生 Codex app-server harness。参见 [OpenAI](/zh-CN/providers/openai) 和 [Codex harness](/zh-CN/plugins/codex-harness)。如果提供商/运行时的划分让你感到困惑,请先阅读 [Agent Runtimes](/zh-CN/concepts/agent-runtimes)。
|
||||
- 插件自动启用也遵循同样的边界:`openai-codex/<model>` 属于 OpenAI 插件,而 Codex 插件则由 `embeddedHarness.runtime: "codex"` 或旧版 `codex/<model>` 引用启用。
|
||||
- CLI 运行时使用相同的划分:选择规范模型引用,例如 `anthropic/claude-*`、`google/gemini-*` 或 `openai/gpt-*`,然后在你想使用本地 CLI 后端时,将 `agents.defaults.embeddedHarness.runtime` 设置为 `claude-cli`、`google-gemini-cli` 或 `codex-cli`。旧版 `claude-cli/*`、`google-gemini-cli/*` 和 `codex-cli/*` 引用会迁移回规范提供商引用,并将运行时单独记录。
|
||||
- GPT-5.5 可通过 `openai/gpt-5.5` 用于直接 API 密钥流量,在 PI 中通过 `openai-codex/gpt-5.5` 用于 Codex OAuth,以及在设置 `embeddedHarness.runtime: "codex"` 时使用原生 Codex app-server harness。
|
||||
|
||||
## 插件拥有的提供商行为
|
||||
|
||||
大多数提供商特定逻辑都位于提供商插件中(`registerProvider(...)`),而 OpenClaw 保留通用推理循环。插件负责新手引导、模型目录、认证环境变量映射、传输/配置规范化、工具 schema 清理、故障切换分类、OAuth 刷新、用量报告、thinking/reasoning 配置等。
|
||||
大多数提供商特定逻辑都位于提供商插件(`registerProvider(...)`)中,而 OpenClaw 保留通用推理循环。插件负责新手引导、模型目录、认证环境变量映射、传输/配置规范化、工具 schema 清理、故障切换分类、OAuth 刷新、用量报告、thinking/reasoning 配置等。
|
||||
|
||||
提供商 SDK 钩子和内置插件示例的完整列表位于 [Provider Plugins](/zh-CN/plugins/sdk-provider-plugins)。如果某个提供商需要完全自定义的请求执行器,那属于另一个更深层的扩展接口。
|
||||
提供商 SDK 钩子的完整列表和内置插件示例位于 [提供商插件](/zh-CN/plugins/sdk-provider-plugins)。如果某个提供商需要完全自定义的请求执行器,那将属于另一种更深层的扩展接口。
|
||||
|
||||
<Note>
|
||||
提供商运行时 `capabilities` 是共享的运行器元数据(提供商家族、转录/工具行为差异、传输/缓存提示)。它不同于[公开能力模型](/zh-CN/plugins/architecture#public-capability-model),后者描述的是插件注册了什么能力(文本推理、语音等)。
|
||||
提供商运行时 `capabilities` 是共享的运行器元数据(提供商家族、转录/工具链特殊行为、传输/缓存提示)。它不同于[公共能力模型](/zh-CN/plugins/architecture#public-capability-model),后者描述的是插件注册了什么(文本推理、语音等)。
|
||||
</Note>
|
||||
|
||||
## API 密钥轮换
|
||||
|
||||
- 支持为选定提供商进行通用提供商轮换。
|
||||
- 可通过以下方式配置多个密钥:
|
||||
- 通过以下方式配置多个密钥:
|
||||
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(单个实时覆盖,最高优先级)
|
||||
- `<PROVIDER>_API_KEYS`(逗号或分号分隔的列表)
|
||||
- `<PROVIDER>_API_KEYS`(逗号或分号分隔列表)
|
||||
- `<PROVIDER>_API_KEY`(主密钥)
|
||||
- `<PROVIDER>_API_KEY_*`(编号列表,例如 `<PROVIDER>_API_KEY_1`)
|
||||
- 对于 Google 提供商,`GOOGLE_API_KEY` 也会作为回退项包含在内。
|
||||
- 对于 Google 提供商,`GOOGLE_API_KEY` 也会作为回退包含在内。
|
||||
- 密钥选择顺序会保留优先级并去重。
|
||||
- 仅在遇到限流响应时,请求才会使用下一个密钥重试(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded`,或周期性用量限制消息)。
|
||||
- 非限流失败会立即失败;不会尝试密钥轮换。
|
||||
- 当所有候选密钥都失败时,将返回最后一次尝试的最终错误。
|
||||
- 仅当响应为速率限制时,请求才会使用下一个密钥重试(例如 `429`、`rate_limit`、`quota`、`resource exhausted`、`Too many concurrent requests`、`ThrottlingException`、`concurrency limit reached`、`workers_ai ... quota limit exceeded`,或周期性用量限制消息)。
|
||||
- 非速率限制失败会立即失败;不会尝试密钥轮换。
|
||||
- 当所有候选密钥都失败时,返回最后一次尝试的最终错误。
|
||||
|
||||
## 内置提供商(pi-ai 目录)
|
||||
|
||||
OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers` 配置;只需设置认证信息并选择一个模型。
|
||||
OpenClaw 内置 pi-ai 目录。这些提供商**不需要** `models.providers` 配置;只需设置认证信息并选择一个模型。
|
||||
|
||||
### OpenAI
|
||||
|
||||
@ -61,17 +61,17 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
- 认证:`OPENAI_API_KEY`
|
||||
- 可选轮换:`OPENAI_API_KEYS`、`OPENAI_API_KEY_1`、`OPENAI_API_KEY_2`,以及 `OPENCLAW_LIVE_OPENAI_KEY`(单个覆盖)
|
||||
- 示例模型:`openai/gpt-5.5`、`openai/gpt-5.4-mini`
|
||||
- 如果特定安装或 API 密钥表现不同,请使用 `openclaw models list --provider openai` 验证账户/模型可用性。
|
||||
- 如果特定安装或 API 密钥表现不同,可使用 `openclaw models list --provider openai` 验证账户/模型可用性。
|
||||
- CLI:`openclaw onboard --auth-choice openai-api-key`
|
||||
- 默认传输为 `auto`(优先 WebSocket,回退到 SSE)
|
||||
- 可按模型通过 `agents.defaults.models["openai/<model>"].params.transport` 覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- 默认传输是 `auto`(优先 WebSocket,回退 SSE)
|
||||
- 可通过 `agents.defaults.models["openai/<model>"].params.transport` 为每个模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- OpenAI Responses WebSocket 预热默认通过 `params.openaiWsWarmup` 启用(`true`/`false`)
|
||||
- OpenAI 优先处理可通过 `agents.defaults.models["openai/<model>"].params.serviceTier` 启用
|
||||
- `/fast` 和 `params.fastMode` 会将直连 `openai/*` Responses 请求映射到 `api.openai.com` 上的 `service_tier=priority`
|
||||
- 当你想使用显式层级而不是共享的 `/fast` 开关时,请使用 `params.serviceTier`
|
||||
- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`)仅应用于发往 `api.openai.com` 的原生 OpenAI 流量,不适用于通用 OpenAI 兼容代理
|
||||
- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示以及 OpenAI reasoning 兼容载荷整形;代理路由不会
|
||||
- `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被有意屏蔽,因为实时 OpenAI API 请求会拒绝它,而当前 Codex 目录也未公开它
|
||||
- OpenAI 优先级处理可通过 `agents.defaults.models["openai/<model>"].params.serviceTier` 启用
|
||||
- `/fast` 和 `params.fastMode` 会将直接 `openai/*` Responses 请求映射为发送到 `api.openai.com` 的 `service_tier=priority`
|
||||
- 当你想使用显式 tier,而不是共享的 `/fast` 切换时,请使用 `params.serviceTier`
|
||||
- 隐藏的 OpenClaw 归属头(`originator`、`version`、`User-Agent`)仅适用于发往 `api.openai.com` 的原生 OpenAI 流量,不适用于通用 OpenAI 兼容代理
|
||||
- 原生 OpenAI 路由还会保留 Responses `store`、提示缓存提示以及 OpenAI reasoning 兼容载荷整形;代理路由则不会
|
||||
- `openai/gpt-5.3-codex-spark` 在 OpenClaw 中被有意屏蔽,因为实时 OpenAI API 请求会拒绝它,而当前 Codex 目录也未暴露它
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -86,9 +86,9 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
- 可选轮换:`ANTHROPIC_API_KEYS`、`ANTHROPIC_API_KEY_1`、`ANTHROPIC_API_KEY_2`,以及 `OPENCLAW_LIVE_ANTHROPIC_KEY`(单个覆盖)
|
||||
- 示例模型:`anthropic/claude-opus-4-6`
|
||||
- CLI:`openclaw onboard --auth-choice apiKey`
|
||||
- 直连公共 Anthropic 请求支持共享 `/fast` 开关和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证流量;OpenClaw 会将其映射到 Anthropic `service_tier`(`auto` 与 `standard_only`)
|
||||
- Anthropic 说明:Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此 OpenClaw 将 Claude CLI 复用和 `claude -p` 用法视为此集成的受认可方式,除非 Anthropic 发布新的政策。
|
||||
- Anthropic setup-token 仍可作为受支持的 OpenClaw token 路径使用,但 OpenClaw 现在在可用时更偏好 Claude CLI 复用和 `claude -p`。
|
||||
- 直接公共 Anthropic 请求支持共享的 `/fast` 切换和 `params.fastMode`,包括发送到 `api.anthropic.com` 的 API 密钥和 OAuth 认证流量;OpenClaw 会将其映射为 Anthropic `service_tier`(`auto` 或 `standard_only`)
|
||||
- Anthropic 说明:Anthropic 员工告诉我们,OpenClaw 风格的 Claude CLI 用法再次被允许,因此除非 Anthropic 发布新政策,否则 OpenClaw 将 Claude CLI 复用和 `claude -p` 用法视为该集成允许的方式。
|
||||
- Anthropic setup-token 仍然作为受支持的 OpenClaw token 路径可用,但 OpenClaw 现在会在可用时优先使用 Claude CLI 复用和 `claude -p`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -101,19 +101,19 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
- 提供商:`openai-codex`
|
||||
- 认证:OAuth(ChatGPT)
|
||||
- PI 模型引用:`openai-codex/gpt-5.5`
|
||||
- 原生 Codex 应用服务器 Codex harness 引用:`openai/gpt-5.5`,并设置 `agents.defaults.embeddedHarness.runtime: "codex"`
|
||||
- 原生 Codex 应用服务器 Codex harness 文档:参见 [Codex harness](/zh-CN/plugins/codex-harness)
|
||||
- 原生 Codex app-server harness 引用:`openai/gpt-5.5`,并设置 `agents.defaults.embeddedHarness.runtime: "codex"`
|
||||
- 原生 Codex app-server harness 文档: [Codex harness](/zh-CN/plugins/codex-harness)
|
||||
- 旧版模型引用:`codex/gpt-*`
|
||||
- 插件边界:`openai-codex/*` 会加载 OpenAI 插件;原生 Codex 应用服务器插件仅由 Codex harness 运行时或旧版 `codex/*` 引用选择。
|
||||
- 插件边界:`openai-codex/*` 会加载 OpenAI 插件;原生 Codex app-server 插件仅通过 Codex harness 运行时或旧版 `codex/*` 引用选择。
|
||||
- CLI:`openclaw onboard --auth-choice openai-codex` 或 `openclaw models auth login --provider openai-codex`
|
||||
- 默认传输为 `auto`(优先 WebSocket,回退到 SSE)
|
||||
- 可按 PI 模型通过 `agents.defaults.models["openai-codex/<model>"].params.transport` 覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- `params.serviceTier` 也会在原生 Codex Responses 请求(`chatgpt.com/backend-api`)中转发
|
||||
- 隐藏的 OpenClaw 归因请求头(`originator`、`version`、`User-Agent`)仅附加到发往 `chatgpt.com/backend-api` 的原生 Codex 流量,不适用于通用 OpenAI 兼容代理
|
||||
- 与直连 `openai/*` 共用相同的 `/fast` 开关和 `params.fastMode` 配置;OpenClaw 会将其映射到 `service_tier=priority`
|
||||
- `openai-codex/gpt-5.5` 使用 Codex 目录的原生 `contextWindow = 400000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限
|
||||
- 政策说明:OpenAI Codex OAuth 明确支持像 OpenClaw 这样的外部工具/工作流。
|
||||
- 当你想使用 Codex OAuth/订阅路径时,请使用 `openai-codex/gpt-5.5`;当你的 API 密钥设置和本地目录公开了公共 API 路径时,请使用 `openai/gpt-5.5`。
|
||||
- 默认传输是 `auto`(优先 WebSocket,回退 SSE)
|
||||
- 可通过 `agents.defaults.models["openai-codex/<model>"].params.transport` 为每个 PI 模型覆盖(`"sse"`、`"websocket"` 或 `"auto"`)
|
||||
- `params.serviceTier` 也会转发到原生 Codex Responses 请求(`chatgpt.com/backend-api`)
|
||||
- 隐藏的 OpenClaw 归属头(`originator`、`version`、`User-Agent`)仅附加在发往 `chatgpt.com/backend-api` 的原生 Codex 流量上,不适用于通用 OpenAI 兼容代理
|
||||
- 与直接 `openai/*` 共享相同的 `/fast` 切换和 `params.fastMode` 配置;OpenClaw 会将其映射为 `service_tier=priority`
|
||||
- `openai-codex/gpt-5.5` 使用 Codex 目录原生的 `contextWindow = 400000` 和默认运行时 `contextTokens = 272000`;可通过 `models.providers.openai-codex.models[].contextTokens` 覆盖运行时上限
|
||||
- 策略说明:OpenAI Codex OAuth 明确支持像 OpenClaw 这样的外部工具/工作流。
|
||||
- 当你想使用 Codex OAuth/订阅路线时,使用 `openai-codex/gpt-5.5`;当你的 API 密钥设置和本地目录暴露公共 API 路线时,使用 `openai/gpt-5.5`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -157,18 +157,18 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
|
||||
- 提供商:`google`
|
||||
- 认证:`GEMINI_API_KEY`
|
||||
- 可选轮换:`GEMINI_API_KEYS`、`GEMINI_API_KEY_1`、`GEMINI_API_KEY_2`、`GOOGLE_API_KEY` 回退项,以及 `OPENCLAW_LIVE_GEMINI_KEY`(单个覆盖)
|
||||
- 可选轮换:`GEMINI_API_KEYS`、`GEMINI_API_KEY_1`、`GEMINI_API_KEY_2`、`GOOGLE_API_KEY` 回退,以及 `OPENCLAW_LIVE_GEMINI_KEY`(单个覆盖)
|
||||
- 示例模型:`google/gemini-3.1-pro-preview`、`google/gemini-3-flash-preview`
|
||||
- 兼容性:使用 `google/gemini-3.1-flash-preview` 的旧版 OpenClaw 配置会被规范化为 `google/gemini-3-flash-preview`
|
||||
- CLI:`openclaw onboard --auth-choice gemini-api-key`
|
||||
- Thinking:`/think adaptive` 使用 Google 动态 thinking。Gemini 3/3.1 不包含固定的 `thinkingLevel`;Gemini 2.5 发送 `thinkingBudget: -1`。
|
||||
- 直连 Gemini 运行还接受 `agents.defaults.models["google/<model>"].params.cachedContent`(或旧版 `cached_content`),以转发提供商原生的 `cachedContents/...` 句柄;Gemini 缓存命中会显示为 OpenClaw `cacheRead`
|
||||
- Thinking:`/think adaptive` 使用 Google 动态 thinking。Gemini 3/3.1 不包含固定的 `thinkingLevel`;Gemini 2.5 会发送 `thinkingBudget: -1`。
|
||||
- 直接 Gemini 运行也接受 `agents.defaults.models["google/<model>"].params.cachedContent`(或旧版 `cached_content`)以转发提供商原生的 `cachedContents/...` 句柄;Gemini 缓存命中会显示为 OpenClaw `cacheRead`
|
||||
|
||||
### Google Vertex 和 Gemini CLI
|
||||
|
||||
- 提供商:`google-vertex`、`google-gemini-cli`
|
||||
- 认证:Vertex 使用 gcloud ADC;Gemini CLI 使用其 OAuth 流程
|
||||
- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告在使用第三方客户端后,其 Google 账户受到了限制。若你选择继续,请查看 Google 条款并使用非关键账户。
|
||||
- 注意:OpenClaw 中的 Gemini CLI OAuth 是非官方集成。一些用户报告在使用第三方客户端后遇到 Google 账号限制。如果你选择继续,请查看 Google 条款并使用非关键账号。
|
||||
- Gemini CLI OAuth 作为内置 `google` 插件的一部分提供。
|
||||
- 先安装 Gemini CLI:
|
||||
- `brew install gemini-cli`
|
||||
@ -176,9 +176,9 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
- 启用:`openclaw plugins enable google`
|
||||
- 登录:`openclaw models auth login --provider google-gemini-cli --set-default`
|
||||
- 默认模型:`google-gemini-cli/gemini-3-flash-preview`
|
||||
- 注意:你**不需要**将 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将 token 存储在 Gateway 网关主机上的认证配置中。
|
||||
- 注意:你**不需要**将 client id 或 secret 粘贴到 `openclaw.json` 中。CLI 登录流程会将 token 存储在 Gateway 网关主机上的认证配置文件中。
|
||||
- 如果登录后请求失败,请在 Gateway 网关主机上设置 `GOOGLE_CLOUD_PROJECT` 或 `GOOGLE_CLOUD_PROJECT_ID`。
|
||||
- Gemini CLI JSON 回复会从 `response` 解析;用量会回退到 `stats`,其中 `stats.cached` 会被规范化为 OpenClaw `cacheRead`。
|
||||
- Gemini CLI JSON 回复从 `response` 解析;用量会回退到 `stats`,其中 `stats.cached` 会被规范化为 OpenClaw `cacheRead`。
|
||||
|
||||
### Z.AI(GLM)
|
||||
|
||||
@ -203,18 +203,18 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
- 示例模型:`kilocode/kilo/auto`
|
||||
- CLI:`openclaw onboard --auth-choice kilocode-api-key`
|
||||
- Base URL:`https://api.kilo.ai/api/gateway/`
|
||||
- 静态回退目录内置了 `kilocode/kilo/auto`;实时发现 `https://api.kilo.ai/api/gateway/models` 还可以进一步扩展运行时目录。
|
||||
- `kilocode/kilo/auto` 背后的确切上游路由由 Kilo Gateway 网关负责,不是在 OpenClaw 中硬编码的。
|
||||
- 静态回退目录内置 `kilocode/kilo/auto`;实时的 `https://api.kilo.ai/api/gateway/models` 发现机制可以进一步扩展运行时目录。
|
||||
- `kilocode/kilo/auto` 背后的精确上游路由由 Kilo Gateway 网关负责,而不是在 OpenClaw 中硬编码。
|
||||
|
||||
设置详情请参阅 [/providers/kilocode](/zh-CN/providers/kilocode)。
|
||||
设置详情请参见 [/providers/kilocode](/zh-CN/providers/kilocode)。
|
||||
|
||||
### 其他内置提供商插件
|
||||
|
||||
| 提供商 | Id | 认证环境变量 | 示例模型 |
|
||||
| ----------------------- | -------------------------------- | ------------------------------------------------------------ | ----------------------------------------------- |
|
||||
| BytePlus | `byteplus` / `byteplus-plan` | `BYTEPLUS_API_KEY` | `byteplus-plan/ark-code-latest` |
|
||||
| BytePlus(国际版) | `byteplus` / `byteplus-plan` | `BYTEPLUS_API_KEY` | `byteplus-plan/ark-code-latest` |
|
||||
| Cerebras | `cerebras` | `CEREBRAS_API_KEY` | `cerebras/zai-glm-4.7` |
|
||||
| Cloudflare AI Gateway 网关 | `cloudflare-ai-gateway` | `CLOUDFLARE_AI_GATEWAY_API_KEY` | — |
|
||||
| Cloudflare AI Gateway | `cloudflare-ai-gateway` | `CLOUDFLARE_AI_GATEWAY_API_KEY` | — |
|
||||
| DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek/deepseek-v4-flash` |
|
||||
| GitHub Copilot | `github-copilot` | `COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN` | — |
|
||||
| Groq | `groq` | `GROQ_API_KEY` | — |
|
||||
@ -223,7 +223,7 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
| Kimi Coding | `kimi` | `KIMI_API_KEY` 或 `KIMICODE_API_KEY` | `kimi/kimi-code` |
|
||||
| MiniMax | `minimax` / `minimax-portal` | `MINIMAX_API_KEY` / `MINIMAX_OAUTH_TOKEN` | `minimax/MiniMax-M2.7` |
|
||||
| Mistral | `mistral` | `MISTRAL_API_KEY` | `mistral/mistral-large-latest` |
|
||||
| Moonshot | `moonshot` | `MOONSHOT_API_KEY` | `moonshot/kimi-k2.6` |
|
||||
| Moonshot AI | `moonshot` | `MOONSHOT_API_KEY` | `moonshot/kimi-k2.6` |
|
||||
| NVIDIA | `nvidia` | `NVIDIA_API_KEY` | `nvidia/nvidia/llama-3.1-nemotron-70b-instruct` |
|
||||
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` | `openrouter/auto` |
|
||||
| Qianfan | `qianfan` | `QIANFAN_API_KEY` | `qianfan/deepseek-v3.2` |
|
||||
@ -231,29 +231,29 @@ OpenClaw 内置了 pi-ai 目录。这些提供商**不需要** `models.providers
|
||||
| StepFun | `stepfun` / `stepfun-plan` | `STEPFUN_API_KEY` | `stepfun/step-3.5-flash` |
|
||||
| Together | `together` | `TOGETHER_API_KEY` | `together/moonshotai/Kimi-K2.5` |
|
||||
| Venice | `venice` | `VENICE_API_KEY` | — |
|
||||
| Vercel AI Gateway 网关 | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway/anthropic/claude-opus-4.6` |
|
||||
| Vercel AI Gateway | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway/anthropic/claude-opus-4.6` |
|
||||
| Volcano Engine(Doubao) | `volcengine` / `volcengine-plan` | `VOLCANO_ENGINE_API_KEY` | `volcengine-plan/ark-code-latest` |
|
||||
| xAI | `xai` | `XAI_API_KEY` | `xai/grok-4` |
|
||||
| Xiaomi | `xiaomi` | `XIAOMI_API_KEY` | `xiaomi/mimo-v2-flash` |
|
||||
|
||||
以下这些特殊行为值得了解:
|
||||
值得了解的一些特殊行为:
|
||||
|
||||
- **OpenRouter** 仅在已验证的 `openrouter.ai` 路由上应用其应用归因请求头和 Anthropic `cache_control` 标记。DeepSeek、Moonshot 和 ZAI 引用可用于 OpenRouter 管理的提示缓存 TTL,但不会收到 Anthropic 缓存标记。作为代理式 OpenAI 兼容路径,它会跳过仅适用于原生 OpenAI 的载荷整形(`serviceTier`、Responses `store`、提示缓存提示、OpenAI reasoning 兼容)。基于 Gemini 的引用仅保留代理 Gemini 的 thought-signature 清理。
|
||||
- **Kilo Gateway 网关** 中基于 Gemini 的引用遵循相同的代理 Gemini 清理路径;`kilocode/kilo/auto` 和其他不支持代理 reasoning 的引用会跳过代理 reasoning 注入。
|
||||
- **MiniMax** API 密钥新手引导会写入显式的纯文本 M2.7 聊天模型定义;图像理解仍保留在插件拥有的 `MiniMax-VL-01` 媒体提供商上。
|
||||
- **xAI** 使用 xAI Responses 路径。`/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、`grok-4` 和 `grok-4-0709` 重写为各自的 `*-fast` 变体。`tool_stream` 默认开启;可通过 `agents.defaults.models["xai/<model>"].params.tool_stream=false` 禁用。
|
||||
- **Cerebras** GLM 模型使用 `zai-glm-4.7` / `zai-glm-4.6`;OpenAI 兼容 Base URL 为 `https://api.cerebras.ai/v1`。
|
||||
- **OpenRouter** 仅在已验证的 `openrouter.ai` 路由上应用其应用归属头和 Anthropic `cache_control` 标记。DeepSeek、Moonshot 和 ZAI 引用可用于 OpenRouter 管理的提示缓存的缓存 TTL,但不会接收 Anthropic 缓存标记。作为代理式的 OpenAI 兼容路径,它会跳过仅限原生 OpenAI 的整形逻辑(`serviceTier`、Responses `store`、提示缓存提示、OpenAI reasoning 兼容处理)。基于 Gemini 的引用仅保留代理 Gemini 的 thought-signature 清理。
|
||||
- **Kilo Gateway** 基于 Gemini 的引用遵循相同的代理 Gemini 清理路径;`kilocode/kilo/auto` 和其他不支持代理 reasoning 的引用会跳过代理 reasoning 注入。
|
||||
- **MiniMax** API 密钥新手引导会写入显式的纯文本 M2.7 聊天模型定义;图像理解仍保留在由插件拥有的 `MiniMax-VL-01` 媒体提供商上。
|
||||
- **xAI** 使用 xAI Responses 路径。`/fast` 或 `params.fastMode: true` 会将 `grok-3`、`grok-3-mini`、`grok-4` 和 `grok-4-0709` 重写为对应的 `*-fast` 变体。`tool_stream` 默认开启;可通过 `agents.defaults.models["xai/<model>"].params.tool_stream=false` 禁用。
|
||||
- **Cerebras** GLM 模型使用 `zai-glm-4.7` / `zai-glm-4.6`;OpenAI 兼容 Base URL 是 `https://api.cerebras.ai/v1`。
|
||||
|
||||
## 通过 `models.providers` 的提供商(自定义/Base URL)
|
||||
|
||||
使用 `models.providers`(或 `models.json`)添加**自定义**提供商或 OpenAI/Anthropic 兼容代理。
|
||||
|
||||
下面许多内置提供商插件已经发布了默认目录。
|
||||
只有当你想覆盖默认 Base URL、请求头或模型列表时,才需要使用显式的 `models.providers.<id>` 条目。
|
||||
仅当你想覆盖默认的 Base URL、headers 或模型列表时,才使用显式的 `models.providers.<id>` 条目。
|
||||
|
||||
### Moonshot AI(Kimi)
|
||||
|
||||
Moonshot 作为内置提供商插件提供。默认使用内置提供商,只有在你需要覆盖 Base URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目:
|
||||
Moonshot 作为内置提供商插件提供。默认情况下使用内置提供商,只有在你需要覆盖 Base URL 或模型元数据时,才添加显式的 `models.providers.moonshot` 条目:
|
||||
|
||||
- 提供商:`moonshot`
|
||||
- 认证:`MOONSHOT_API_KEY`
|
||||
@ -308,13 +308,13 @@ Kimi Coding 使用 Moonshot AI 的 Anthropic 兼容端点:
|
||||
}
|
||||
```
|
||||
|
||||
旧版 `kimi/k2p5` 仍然作为兼容模型 Id 被接受。
|
||||
旧版 `kimi/k2p5` 仍然作为兼容模型 id 被接受。
|
||||
|
||||
### Volcano Engine(Doubao)
|
||||
|
||||
Volcano Engine(火山引擎)提供对中国区 Doubao 和其他模型的访问。
|
||||
Volcano Engine(火山引擎)在中国提供对 Doubao 和其他模型的访问。
|
||||
|
||||
- 提供商:`volcengine`(编码方案:`volcengine-plan`)
|
||||
- 提供商:`volcengine`(编码场景:`volcengine-plan`)
|
||||
- 认证:`VOLCANO_ENGINE_API_KEY`
|
||||
- 示例模型:`volcengine-plan/ark-code-latest`
|
||||
- CLI:`openclaw onboard --auth-choice volcengine-api-key`
|
||||
@ -327,9 +327,9 @@ Volcano Engine(火山引擎)提供对中国区 Doubao 和其他模型的访
|
||||
}
|
||||
```
|
||||
|
||||
新手引导默认使用编码接口,但通用 `volcengine/*` 目录会同时注册。
|
||||
新手引导默认使用编码接口,但通用的 `volcengine/*` 目录会同时注册。
|
||||
|
||||
在新手引导/配置模型选择器中,Volcengine 认证选项会优先显示 `volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商限定的选择器。
|
||||
在新手引导/配置模型选择器中,Volcengine 认证选项会优先显示 `volcengine/*` 和 `volcengine-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商范围过滤的选择器。
|
||||
|
||||
可用模型:
|
||||
|
||||
@ -349,9 +349,9 @@ Volcano Engine(火山引擎)提供对中国区 Doubao 和其他模型的访
|
||||
|
||||
### BytePlus(国际版)
|
||||
|
||||
BytePlus ARK 为国际用户提供与 Volcano Engine 相同的模型访问能力。
|
||||
BytePlus ARK 为国际用户提供与 Volcano Engine 相同模型的访问能力。
|
||||
|
||||
- 提供商:`byteplus`(编码方案:`byteplus-plan`)
|
||||
- 提供商:`byteplus`(编码场景:`byteplus-plan`)
|
||||
- 认证:`BYTEPLUS_API_KEY`
|
||||
- 示例模型:`byteplus-plan/ark-code-latest`
|
||||
- CLI:`openclaw onboard --auth-choice byteplus-api-key`
|
||||
@ -364,9 +364,9 @@ BytePlus ARK 为国际用户提供与 Volcano Engine 相同的模型访问能力
|
||||
}
|
||||
```
|
||||
|
||||
新手引导默认使用编码接口,但通用 `byteplus/*` 目录会同时注册。
|
||||
新手引导默认使用编码接口,但通用的 `byteplus/*` 目录会同时注册。
|
||||
|
||||
在新手引导/配置模型选择器中,BytePlus(国际版)认证选项会优先显示 `byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商限定的选择器。
|
||||
在新手引导/配置模型选择器中,BytePlus(国际版)认证选项会优先显示 `byteplus/*` 和 `byteplus-plan/*` 两类条目。如果这些模型尚未加载,OpenClaw 会回退到未过滤的目录,而不是显示一个空的按提供商范围过滤的选择器。
|
||||
|
||||
可用模型:
|
||||
|
||||
@ -420,16 +420,16 @@ MiniMax 通过 `models.providers` 配置,因为它使用自定义端点:
|
||||
- MiniMax API 密钥(CN):`--auth-choice minimax-cn-api`
|
||||
- 认证:`minimax` 使用 `MINIMAX_API_KEY`;`minimax-portal` 使用 `MINIMAX_OAUTH_TOKEN` 或 `MINIMAX_API_KEY`
|
||||
|
||||
设置详情、模型选项和配置片段请参阅 [/providers/minimax](/zh-CN/providers/minimax)。
|
||||
设置详情、模型选项和配置片段请参见 [/providers/minimax](/zh-CN/providers/minimax)。
|
||||
|
||||
在 MiniMax 的 Anthropic 兼容流式传输路径上,OpenClaw 默认禁用 thinking,除非你显式设置它;而 `/fast on` 会将 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。
|
||||
在 MiniMax 的 Anthropic 兼容流式传输路径上,OpenClaw 默认禁用 thinking,除非你显式设置它;`/fast on` 会将 `MiniMax-M2.7` 重写为 `MiniMax-M2.7-highspeed`。
|
||||
|
||||
插件拥有的能力拆分:
|
||||
插件拥有的能力划分:
|
||||
|
||||
- 文本/聊天默认仍使用 `minimax/MiniMax-M2.7`
|
||||
- 文本/聊天默认保持为 `minimax/MiniMax-M2.7`
|
||||
- 图像生成使用 `minimax/image-01` 或 `minimax-portal/image-01`
|
||||
- 图像理解在两条 MiniMax 认证路径上都使用由插件拥有的 `MiniMax-VL-01`
|
||||
- Web 搜索仍使用提供商 Id `minimax`
|
||||
- 图像理解在两种 MiniMax 认证路径上都使用由插件拥有的 `MiniMax-VL-01`
|
||||
- Web 搜索保持使用提供商 id `minimax`
|
||||
|
||||
### LM Studio
|
||||
|
||||
@ -439,7 +439,7 @@ LM Studio 作为内置提供商插件提供,并使用原生 API:
|
||||
- 认证:`LM_API_TOKEN`
|
||||
- 默认推理 Base URL:`http://localhost:1234/v1`
|
||||
|
||||
然后设置一个模型(替换为 `http://localhost:1234/api/v1/models` 返回的某个 Id):
|
||||
然后设置一个模型(替换为 `http://localhost:1234/api/v1/models` 返回的某个 id):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -449,16 +449,16 @@ LM Studio 作为内置提供商插件提供,并使用原生 API:
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw 使用 LM Studio 原生的 `/api/v1/models` 和 `/api/v1/models/load` 进行设备发现 + 自动加载,并默认使用 `/v1/chat/completions` 进行推理。设置和故障排除请参阅 [/providers/lmstudio](/zh-CN/providers/lmstudio)。
|
||||
OpenClaw 使用 LM Studio 原生的 `/api/v1/models` 和 `/api/v1/models/load` 进行发现 + 自动加载,默认使用 `/v1/chat/completions` 进行推理。设置和故障排除请参见 [/providers/lmstudio](/zh-CN/providers/lmstudio)。
|
||||
|
||||
### Ollama
|
||||
|
||||
Ollama 作为内置提供商插件提供,并使用 Ollama 原生 API:
|
||||
Ollama 作为内置提供商插件提供,并使用 Ollama 的原生 API:
|
||||
|
||||
- 提供商:`ollama`
|
||||
- 认证:无需(本地服务器)
|
||||
- 示例模型:`ollama/llama3.3`
|
||||
- 安装:[https://ollama.com/download](https://ollama.com/download)
|
||||
- 安装: [https://ollama.com/download](https://ollama.com/download)
|
||||
|
||||
```bash
|
||||
# 安装 Ollama,然后拉取一个模型:
|
||||
@ -473,23 +473,23 @@ ollama pull llama3.3
|
||||
}
|
||||
```
|
||||
|
||||
当你通过 `OLLAMA_API_KEY` 选择启用时,系统会在本地 `http://127.0.0.1:11434` 检测 Ollama,内置提供商插件也会将 Ollama 直接添加到 `openclaw onboard` 和模型选择器中。关于新手引导、云端/本地模式以及自定义配置,请参阅 [/providers/ollama](/zh-CN/providers/ollama)。
|
||||
当你通过 `OLLAMA_API_KEY` 选择启用时,系统会在本地 `http://127.0.0.1:11434` 检测 Ollama,内置提供商插件还会将 Ollama 直接添加到 `openclaw onboard` 和模型选择器中。有关新手引导、云端/本地模式和自定义配置,请参见 [/providers/ollama](/zh-CN/providers/ollama)。
|
||||
|
||||
### vLLM
|
||||
|
||||
vLLM 作为内置提供商插件提供,用于本地/自托管的 OpenAI 兼容服务器:
|
||||
vLLM 作为内置提供商插件提供,适用于本地/自托管的 OpenAI 兼容服务器:
|
||||
|
||||
- 提供商:`vllm`
|
||||
- 认证:可选(取决于你的服务器)
|
||||
- 默认 Base URL:`http://127.0.0.1:8000/v1`
|
||||
|
||||
要在本地启用自动发现(如果你的服务器不强制认证,任意值都可以):
|
||||
要在本地选择启用自动发现(如果你的服务器不强制认证,任意值都可以):
|
||||
|
||||
```bash
|
||||
export VLLM_API_KEY="vllm-local"
|
||||
```
|
||||
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 Id):
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 id):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -499,23 +499,23 @@ export VLLM_API_KEY="vllm-local"
|
||||
}
|
||||
```
|
||||
|
||||
详情请参阅 [/providers/vllm](/zh-CN/providers/vllm)。
|
||||
详情请参见 [/providers/vllm](/zh-CN/providers/vllm)。
|
||||
|
||||
### SGLang
|
||||
|
||||
SGLang 作为内置提供商插件提供,用于高速自托管的 OpenAI 兼容服务器:
|
||||
SGLang 作为内置提供商插件提供,适用于高速自托管的 OpenAI 兼容服务器:
|
||||
|
||||
- 提供商:`sglang`
|
||||
- 认证:可选(取决于你的服务器)
|
||||
- 默认 Base URL:`http://127.0.0.1:30000/v1`
|
||||
|
||||
要在本地启用自动发现(如果你的服务器不强制认证,任意值都可以):
|
||||
要在本地选择启用自动发现(如果你的服务器不强制认证,任意值都可以):
|
||||
|
||||
```bash
|
||||
export SGLANG_API_KEY="sglang-local"
|
||||
```
|
||||
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 Id):
|
||||
然后设置一个模型(替换为 `/v1/models` 返回的某个 id):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -525,7 +525,7 @@ export SGLANG_API_KEY="sglang-local"
|
||||
}
|
||||
```
|
||||
|
||||
详情请参阅 [/providers/sglang](/zh-CN/providers/sglang)。
|
||||
详情请参见 [/providers/sglang](/zh-CN/providers/sglang)。
|
||||
|
||||
### 本地代理(LM Studio、vLLM、LiteLLM 等)
|
||||
|
||||
@ -571,12 +571,13 @@ export SGLANG_API_KEY="sglang-local"
|
||||
- `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }`
|
||||
- `contextWindow: 200000`
|
||||
- `maxTokens: 8192`
|
||||
- 建议:设置与你的代理/模型限制相匹配的显式值。
|
||||
- 建议:设置与你的代理/模型限制匹配的显式值。
|
||||
- 对于非原生端点上的 `api: "openai-completions"`(任何 host 不是 `api.openai.com` 的非空 `baseUrl`),OpenClaw 会强制 `compat.supportsDeveloperRole: false`,以避免提供商因不支持 `developer` 角色而返回 400 错误。
|
||||
- 代理式 OpenAI 兼容路由也会跳过仅适用于原生 OpenAI 的请求整形:没有 `service_tier`,没有 Responses `store`,没有 Completions `store`,没有提示缓存提示,没有 OpenAI reasoning 兼容载荷整形,也没有隐藏的 OpenClaw 归因请求头。
|
||||
- 代理式 OpenAI 兼容路由也会跳过仅限原生 OpenAI 的请求整形:不使用 `service_tier`,不使用 Responses `store`,不使用 Completions `store`,不使用提示缓存提示,不进行 OpenAI reasoning 兼容载荷整形,也不添加隐藏的 OpenClaw 归属头。
|
||||
- 对于需要供应商特定字段的 OpenAI 兼容 Completions 代理,可设置 `agents.defaults.models["provider/model"].params.extra_body`(或 `extraBody`),以将额外 JSON 合并到出站请求体中。
|
||||
- 如果 `baseUrl` 为空或省略,OpenClaw 会保留默认 OpenAI 行为(即解析到 `api.openai.com`)。
|
||||
- 出于安全考虑,即使在非原生 `openai-completions` 端点上显式设置了 `compat.supportsDeveloperRole: true`,仍会被覆盖。
|
||||
- 对于 vLLM chat-template 控制,可设置 `agents.defaults.models["provider/model"].params.chat_template_kwargs`。当会话 thinking level 关闭时,OpenClaw 会自动为 `vllm/nemotron-3-*` 发送 `enable_thinking: false` 和 `force_nonempty_content: true`。
|
||||
- 如果 `baseUrl` 为空/省略,OpenClaw 会保留默认 OpenAI 行为(即解析到 `api.openai.com`)。
|
||||
- 出于安全考虑,即使显式设置了 `compat.supportsDeveloperRole: true`,在非原生 `openai-completions` 端点上仍会被覆盖。
|
||||
|
||||
## CLI 示例
|
||||
|
||||
@ -586,11 +587,11 @@ openclaw models set opencode/claude-opus-4-6
|
||||
openclaw models list
|
||||
```
|
||||
|
||||
另请参阅:[配置](/zh-CN/gateway/configuration),其中包含完整配置示例。
|
||||
另请参见: [配置](/zh-CN/gateway/configuration) 了解完整配置示例。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [Models](/zh-CN/concepts/models) — 模型配置和别名
|
||||
- [模型故障切换](/zh-CN/concepts/model-failover) — 回退链和重试行为
|
||||
- [配置参考](/zh-CN/gateway/config-agents#agent-defaults) — 模型配置键
|
||||
- [Providers](/zh-CN/providers) — 按提供商分类的设置指南
|
||||
- [提供商](/zh-CN/providers) — 按提供商划分的设置指南
|
||||
|
||||
@ -2,19 +2,19 @@
|
||||
read_when:
|
||||
- 调整智能体默认设置(模型、思考、工作区、心跳、媒体、Skills)
|
||||
- 配置多智能体路由和绑定
|
||||
- 调整会话、消息投递和对话模式行为
|
||||
summary: 智能体默认设置、多智能体路由、会话、消息和对话配置
|
||||
- 调整会话、消息投递和通话模式行为
|
||||
summary: 智能体默认设置、多智能体路由、会话、消息和通话配置
|
||||
title: 配置 — 智能体
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T02:22:23Z"
|
||||
generated_at: "2026-04-26T03:01:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 4ef141ed441b2beeb3dafbe02a50b10f770c902e44b5953997f15676e6c0ecd5
|
||||
source_hash: 71054e9f1141454c1148d889df353b44df04d9f90d477976dd97f8b45c5abace
|
||||
source_path: gateway/config-agents.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
`agents.*`、`multiAgent.*`、`session.*`、`messages.*` 和 `talk.*` 下按智能体作用域划分的配置键。关于渠道、工具、Gateway 网关运行时及其他顶层键,请参见 [配置参考](/zh-CN/gateway/configuration-reference)。
|
||||
`agents.*`、`multiAgent.*`、`session.*`、`messages.*` 和 `talk.*` 下按智能体范围划分的配置键。关于渠道、工具、Gateway 网关运行时以及其他顶级键,请参阅 [配置参考](/zh-CN/gateway/configuration-reference)。
|
||||
|
||||
## 智能体默认设置
|
||||
|
||||
@ -30,7 +30,7 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.repoRoot`
|
||||
|
||||
可选的仓库根目录,会显示在系统提示中的 Runtime 行。如果未设置,OpenClaw 会从工作区开始向上遍历并自动检测。
|
||||
可选的仓库根目录,会显示在系统提示词的 Runtime 行中。如果未设置,OpenClaw 会从工作区向上遍历并自动检测。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -56,8 +56,8 @@ x-i18n:
|
||||
```
|
||||
|
||||
- 省略 `agents.defaults.skills`,则默认 Skills 不受限制。
|
||||
- 省略 `agents.list[].skills`,则继承默认值。
|
||||
- 将 `agents.list[].skills: []` 设为空数组表示不使用任何 Skills。
|
||||
- 省略 `agents.list[].skills` 以继承默认值。
|
||||
- 设置 `agents.list[].skills: []` 表示不启用任何 Skills。
|
||||
- 非空的 `agents.list[].skills` 列表就是该智能体的最终集合;它不会与默认值合并。
|
||||
|
||||
### `agents.defaults.skipBootstrap`
|
||||
@ -72,10 +72,10 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.contextInjection`
|
||||
|
||||
控制何时将工作区引导文件注入系统提示。默认值:`"always"`。
|
||||
控制何时将工作区引导文件注入系统提示词。默认值:`"always"`。
|
||||
|
||||
- `"continuation-skip"`:在安全的续接轮次中(完成一次 assistant 响应之后),跳过工作区引导内容的再次注入,以减少提示大小。心跳运行和压缩后的重试仍会重建上下文。
|
||||
- `"never"`:在每一轮都禁用工作区引导和上下文文件注入。仅建议用于完全自行管理提示生命周期的智能体(自定义上下文引擎、自行构建上下文的原生运行时,或专门的无引导工作流)。心跳轮次和压缩恢复轮次也会跳过注入。
|
||||
- `"continuation-skip"`:安全的续接轮次(在助手完成一次响应之后)会跳过工作区引导内容的再次注入,从而减少提示词大小。Heartbeat 运行和压缩后的重试仍会重建上下文。
|
||||
- `"never"`:在每一轮都禁用工作区引导和上下文文件注入。仅将其用于完全自行管理提示词生命周期的智能体(自定义上下文引擎、构建自身上下文的原生运行时,或专门的不含引导工作流)。Heartbeat 和压缩恢复轮次也会跳过注入。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -105,12 +105,12 @@ x-i18n:
|
||||
|
||||
### `agents.defaults.bootstrapPromptTruncationWarning`
|
||||
|
||||
控制当引导上下文被截断时,向智能体显示的警告文本。
|
||||
控制引导上下文被截断时向智能体显示的警告文本。
|
||||
默认值:`"once"`。
|
||||
|
||||
- `"off"`:绝不将警告文本注入系统提示。
|
||||
- `"off"`:绝不将警告文本注入系统提示词。
|
||||
- `"once"`:对每个唯一的截断签名只注入一次警告(推荐)。
|
||||
- `"always"`:只要存在截断,每次运行都注入警告。
|
||||
- `"always"`:只要存在截断,就在每次运行时注入警告。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -120,7 +120,7 @@ x-i18n:
|
||||
|
||||
### 上下文预算归属映射
|
||||
|
||||
OpenClaw 有多个高容量的提示 / 上下文预算,这些预算会按子系统有意拆分,而不是全部通过一个通用开关统一控制。
|
||||
OpenClaw 有多个高容量的提示词 / 上下文预算,这些预算会按子系统有意拆分,而不是全部通过一个通用开关来控制。
|
||||
|
||||
- `agents.defaults.bootstrapMaxChars` /
|
||||
`agents.defaults.bootstrapTotalMaxChars`:
|
||||
@ -129,13 +129,13 @@ OpenClaw 有多个高容量的提示 / 上下文预算,这些预算会按子
|
||||
一次性的 `/new` 和 `/reset` 启动前导内容,包括最近的每日
|
||||
`memory/*.md` 文件。
|
||||
- `skills.limits.*`:
|
||||
注入系统提示中的精简 Skills 列表。
|
||||
注入系统提示词中的精简 Skills 列表。
|
||||
- `agents.defaults.contextLimits.*`:
|
||||
有界的运行时摘录和由运行时拥有的注入内容块。
|
||||
有边界的运行时摘录和由运行时拥有的注入块。
|
||||
- `memory.qmd.limits.*`:
|
||||
已索引的内存搜索片段和注入大小控制。
|
||||
已索引的 memory 搜索片段及注入大小控制。
|
||||
|
||||
只有当某个智能体需要不同预算时,才使用对应的按智能体覆盖项:
|
||||
仅当某个智能体需要不同预算时,才使用对应的按智能体覆盖项:
|
||||
|
||||
- `agents.list[].skillsLimits.maxSkillsPromptChars`
|
||||
- `agents.list[].contextLimits.*`
|
||||
@ -163,7 +163,7 @@ OpenClaw 有多个高容量的提示 / 上下文预算,这些预算会按子
|
||||
|
||||
#### `agents.defaults.contextLimits`
|
||||
|
||||
为有界运行时上下文表面提供共享默认值。
|
||||
用于有边界运行时上下文表面的共享默认值。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -180,14 +180,14 @@ OpenClaw 有多个高容量的提示 / 上下文预算,这些预算会按子
|
||||
}
|
||||
```
|
||||
|
||||
- `memoryGetMaxChars`:`memory_get` 摘录的默认上限;超过后会添加截断元数据和继续提示。
|
||||
- `memoryGetDefaultLines`:当省略 `lines` 时,`memory_get` 默认使用的行窗口。
|
||||
- `memoryGetMaxChars`:`memory_get` 摘录在添加截断元数据和续接提示前的默认上限。
|
||||
- `memoryGetDefaultLines`:省略 `lines` 时,`memory_get` 的默认行数窗口。
|
||||
- `toolResultMaxChars`:用于持久化结果和溢出恢复的实时工具结果上限。
|
||||
- `postCompactionMaxChars`:在压缩后刷新注入期间使用的 `AGENTS.md` 摘录上限。
|
||||
- `postCompactionMaxChars`:压缩后刷新注入期间使用的 `AGENTS.md` 摘录上限。
|
||||
|
||||
#### `agents.list[].contextLimits`
|
||||
|
||||
对共享 `contextLimits` 开关的按智能体覆盖。省略的字段会继承 `agents.defaults.contextLimits`。
|
||||
共享 `contextLimits` 开关的按智能体覆盖项。省略的字段会继承自 `agents.defaults.contextLimits`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -213,7 +213,7 @@ OpenClaw 有多个高容量的提示 / 上下文预算,这些预算会按子
|
||||
|
||||
#### `skills.limits.maxSkillsPromptChars`
|
||||
|
||||
注入系统提示中的精简 Skills 列表的全局上限。这不会影响按需读取 `SKILL.md` 文件。
|
||||
注入系统提示词中的精简 Skills 列表的全局上限。这不会影响按需读取 `SKILL.md` 文件。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -227,7 +227,7 @@ OpenClaw 有多个高容量的提示 / 上下文预算,这些预算会按子
|
||||
|
||||
#### `agents.list[].skillsLimits.maxSkillsPromptChars`
|
||||
|
||||
Skills 提示预算的按智能体覆盖。
|
||||
Skills 提示词预算的按智能体覆盖项。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -246,11 +246,11 @@ Skills 提示预算的按智能体覆盖。
|
||||
|
||||
### `agents.defaults.imageMaxDimensionPx`
|
||||
|
||||
在调用提供商之前,transcript / 工具图像块中图像最长边允许的最大像素尺寸。
|
||||
在调用提供商之前,转录内容 / 工具图像块中图像最长边的最大像素尺寸。
|
||||
默认值:`1200`。
|
||||
|
||||
较低的值通常会减少视觉 token 用量和请求负载大小,适合截图较多的运行场景。
|
||||
较高的值则能保留更多视觉细节。
|
||||
较低的值通常会减少视觉 token 使用量,以及以截图为主的运行中的请求负载大小。
|
||||
较高的值则可保留更多视觉细节。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -260,7 +260,7 @@ Skills 提示预算的按智能体覆盖。
|
||||
|
||||
### `agents.defaults.userTimezone`
|
||||
|
||||
用于系统提示上下文的时区(不影响消息时间戳)。如果未设置,则回退到主机时区。
|
||||
系统提示词上下文所使用的时区(不影响消息时间戳)。默认回退到主机时区。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -270,7 +270,7 @@ Skills 提示预算的按智能体覆盖。
|
||||
|
||||
### `agents.defaults.timeFormat`
|
||||
|
||||
系统提示中的时间格式。默认值:`auto`(操作系统偏好)。
|
||||
系统提示词中的时间格式。默认值:`auto`(操作系统偏好)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -327,52 +327,53 @@ Skills 提示预算的按智能体覆盖。
|
||||
}
|
||||
```
|
||||
|
||||
- `model`:既接受字符串(`"provider/model"`),也接受对象(`{ primary, fallbacks }`)。
|
||||
- `model`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 字符串形式只设置主模型。
|
||||
- 对象形式设置主模型以及按顺序排列的故障切换模型。
|
||||
- `imageModel`:既接受字符串(`"provider/model"`),也接受对象(`{ primary, fallbacks }`)。
|
||||
- 作为 `image` 工具路径的视觉模型配置使用。
|
||||
- 当所选 / 默认模型无法接受图像输入时,也用作回退路由。
|
||||
- `imageGenerationModel`:既接受字符串(`"provider/model"`),也接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于共享的图像生成能力,以及未来任何生成图像的工具 / 插件表面。
|
||||
- 典型值:`google/gemini-3.1-flash-image-preview`(用于原生 Gemini 图像生成)、`fal/fal-ai/flux/dev`(用于 fal)、`openai/gpt-image-2`(用于 OpenAI Images),或 `openai/gpt-image-1.5`(用于支持透明背景的 OpenAI PNG/WebP 输出)。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商认证(例如:`google/*` 对应 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/gpt-image-2` / `openai/gpt-image-1.5` 对应 `OPENAI_API_KEY` 或 OpenAI Codex OAuth,`fal/*` 对应 `FAL_KEY`)。
|
||||
- 如果省略,`image_generate` 仍可推断带有认证的默认提供商。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的图像生成提供商。
|
||||
- `musicGenerationModel`:既接受字符串(`"provider/model"`),也接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于共享的音乐生成能力以及内置的 `music_generate` 工具。
|
||||
- 对象形式会设置主模型以及按顺序排列的故障切换模型。
|
||||
- `imageModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 由 `image` 工具路径用作其视觉模型配置。
|
||||
- 当已选 / 默认模型无法接受图像输入时,也会用作回退路由。
|
||||
- `imageGenerationModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 由共享的图像生成能力以及任何未来会生成图像的工具 / 插件表面使用。
|
||||
- 典型值:用于原生 Gemini 图像生成的 `google/gemini-3.1-flash-image-preview`,用于 fal 的 `fal/fal-ai/flux/dev`,用于 OpenAI Images 的 `openai/gpt-image-2`,或用于支持透明背景 OpenAI PNG/WebP 输出的 `openai/gpt-image-1.5`。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商凭证(例如,`google/*` 使用 `GEMINI_API_KEY` 或 `GOOGLE_API_KEY`,`openai/gpt-image-2` / `openai/gpt-image-1.5` 使用 `OPENAI_API_KEY` 或 OpenAI Codex OAuth,`fal/*` 使用 `FAL_KEY`)。
|
||||
- 如果省略,`image_generate` 仍可推断出一个带凭证的默认提供商。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的图像生成提供商。
|
||||
- `musicGenerationModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 由共享的音乐生成能力和内置 `music_generate` 工具使用。
|
||||
- 典型值:`google/lyria-3-clip-preview`、`google/lyria-3-pro-preview` 或 `minimax/music-2.6`。
|
||||
- 如果省略,`music_generate` 仍可推断带有认证的默认提供商。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的音乐生成提供商。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商认证 / API 密钥。
|
||||
- `videoGenerationModel`:既接受字符串(`"provider/model"`),也接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于共享的视频生成能力以及内置的 `video_generate` 工具。
|
||||
- 如果省略,`music_generate` 仍可推断出一个带凭证的默认提供商。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的音乐生成提供商。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商凭证 / API key。
|
||||
- `videoGenerationModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 由共享的视频生成能力和内置 `video_generate` 工具使用。
|
||||
- 典型值:`qwen/wan2.6-t2v`、`qwen/wan2.6-i2v`、`qwen/wan2.6-r2v`、`qwen/wan2.6-r2v-flash` 或 `qwen/wan2.7-r2v`。
|
||||
- 如果省略,`video_generate` 仍可推断带有认证的默认提供商。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的视频生成提供商。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商认证 / API 密钥。
|
||||
- 如果省略,`video_generate` 仍可推断出一个带凭证的默认提供商。它会先尝试当前默认提供商,然后按提供商 id 顺序尝试其余已注册的视频生成提供商。
|
||||
- 如果你直接选择某个提供商 / 模型,也要配置匹配的提供商凭证 / API key。
|
||||
- 内置的 Qwen 视频生成提供商最多支持 1 个输出视频、1 张输入图像、4 个输入视频、10 秒时长,以及提供商级别的 `size`、`aspectRatio`、`resolution`、`audio` 和 `watermark` 选项。
|
||||
- `pdfModel`:既接受字符串(`"provider/model"`),也接受对象(`{ primary, fallbacks }`)。
|
||||
- 用于 `pdf` 工具的模型路由。
|
||||
- 如果省略,PDF 工具会依次回退到 `imageModel`,再回退到解析后的会话 / 默认模型。
|
||||
- `pdfModel`:既可接受字符串(`"provider/model"`),也可接受对象(`{ primary, fallbacks }`)。
|
||||
- 由 `pdf` 工具用于模型路由。
|
||||
- 如果省略,PDF 工具会先回退到 `imageModel`,再回退到解析后的会话 / 默认模型。
|
||||
- `pdfMaxBytesMb`:当调用时未传入 `maxBytesMb` 时,`pdf` 工具使用的默认 PDF 大小限制。
|
||||
- `pdfMaxPages`:`pdf` 工具在提取回退模式下默认考虑的最大页数。
|
||||
- `verboseDefault`:智能体的默认详细级别。取值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。
|
||||
- `verboseDefault`:智能体的默认详细输出级别。取值:`"off"`、`"on"`、`"full"`。默认值:`"off"`。
|
||||
- `elevatedDefault`:智能体的默认增强输出级别。取值:`"off"`、`"on"`、`"ask"`、`"full"`。默认值:`"on"`。
|
||||
- `model.primary`:格式为 `provider/model`(例如,`openai/gpt-5.5` 用于 API 密钥访问,或 `openai-codex/gpt-5.5` 用于 Codex OAuth)。如果你省略提供商,OpenClaw 会先尝试别名,然后尝试与该精确模型 id 唯一匹配的已配置提供商,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此建议优先使用显式的 `provider/model`)。如果该提供商不再暴露已配置的默认模型,OpenClaw 会回退到第一个已配置的提供商 / 模型,而不是暴露一个陈旧的、已移除提供商默认值。
|
||||
- `models`:为 `/model` 配置的模型目录和允许列表。每个条目都可以包含 `alias`(快捷方式)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`、`responsesServerCompaction`、`responsesCompactThreshold`、`extra_body` / `extraBody`)。
|
||||
- 安全编辑:使用 `openclaw config set agents.defaults.models '<json>' --strict-json --merge` 添加条目。除非传入 `--replace`,否则 `config set` 会拒绝会移除现有允许列表条目的替换操作。
|
||||
- 以提供商为作用域的配置 / 新手引导流程会将所选提供商模型合并到此映射中,并保留已配置的其他无关提供商。
|
||||
- 对于直接使用的 OpenAI Responses 模型,默认会自动启用服务端压缩。使用 `params.responsesServerCompaction: false` 可停止注入 `context_management`,或使用 `params.responsesCompactThreshold` 覆盖阈值。参见 [OpenAI 服务端压缩](/zh-CN/providers/openai#server-side-compaction-responses-api)。
|
||||
- `params`:适用于所有模型的全局默认提供商参数。设置在 `agents.defaults.params`(例如 `{ cacheRetention: "long" }`)。
|
||||
- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(按模型)覆盖,然后 `agents.list[].params`(匹配智能体 id)再按键覆盖。详情参见 [提示缓存](/zh-CN/reference/prompt-caching)。
|
||||
- `params.extra_body` / `params.extraBody`:高级透传 JSON,会合并进 OpenAI 兼容代理的 `api: "openai-completions"` 请求体中。如果它与生成的请求键冲突,则额外请求体优先;非原生 completions 路由之后仍会剥离仅适用于 OpenAI 的 `store`。
|
||||
- `embeddedHarness`:默认的低层嵌入式智能体运行时策略。未指定时默认使用 OpenClaw Pi。使用 `runtime: "pi"` 可强制使用内置 PI harness,使用 `runtime: "auto"` 可让已注册的插件 harness 认领受支持的模型,或使用已注册的 harness id,如 `runtime: "codex"`。设置 `fallback: "none"` 可禁用自动 PI 回退。显式插件运行时(如 `codex`)默认会在关闭模式下失败,除非你在相同覆盖作用域中设置 `fallback: "pi"`。请将模型引用保持为规范形式 `provider/model`;通过运行时配置选择 Codex、Claude CLI、Gemini CLI 和其他执行后端,而不是使用旧式运行时提供商前缀。参见 [Agent Runtimes](/zh-CN/concepts/agent-runtimes),了解这与提供商 / 模型选择的区别。
|
||||
- 修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及回退添加 / 删除命令)会保存为规范对象形式,并尽可能保留现有回退列表。
|
||||
- `maxConcurrent`:跨会话并行运行的最大智能体数量(每个会话内部仍然串行)。默认值:4。
|
||||
- `model.primary`:格式为 `provider/model`(例如,使用 API key 访问时为 `openai/gpt-5.5`,使用 Codex OAuth 时为 `openai-codex/gpt-5.5`)。如果你省略提供商,OpenClaw 会先尝试别名,然后尝试与该精确模型 id 唯一匹配的已配置提供商,最后才回退到已配置的默认提供商(这是已弃用的兼容行为,因此更推荐显式使用 `provider/model`)。如果该提供商不再暴露已配置的默认模型,OpenClaw 会回退到第一个已配置的提供商 / 模型,而不是显示一个过时且已移除提供商的默认值。
|
||||
- `models`:用于 `/model` 的已配置模型目录和允许列表。每个条目都可包含 `alias`(快捷名)和 `params`(提供商特定参数,例如 `temperature`、`maxTokens`、`cacheRetention`、`context1m`、`responsesServerCompaction`、`responsesCompactThreshold`、`chat_template_kwargs`、`extra_body` / `extraBody`)。
|
||||
- 安全编辑:使用 `openclaw config set agents.defaults.models '<json>' --strict-json --merge` 添加条目。除非你传入 `--replace`,否则 `config set` 会拒绝可能移除现有允许列表条目的替换操作。
|
||||
- 按提供商范围的配置 / 新手引导流程会将所选提供商模型合并到此映射中,并保留已配置的其他无关提供商。
|
||||
- 对于直接使用的 OpenAI Responses 模型,会自动启用服务端压缩。使用 `params.responsesServerCompaction: false` 可停止注入 `context_management`,或者使用 `params.responsesCompactThreshold` 覆盖阈值。参见 [OpenAI 服务端压缩](/zh-CN/providers/openai#server-side-compaction-responses-api)。
|
||||
- `params`:应用到所有模型的全局默认提供商参数。设置在 `agents.defaults.params`(例如 `{ cacheRetention: "long" }`)。
|
||||
- `params` 合并优先级(配置):`agents.defaults.params`(全局基础)会被 `agents.defaults.models["provider/model"].params`(按模型)覆盖,然后 `agents.list[].params`(匹配的智能体 id)会按键进一步覆盖。详见 [Prompt Caching](/zh-CN/reference/prompt-caching)。
|
||||
- `params.extra_body` / `params.extraBody`:高级透传 JSON,会合并到 OpenAI 兼容代理的 `api: "openai-completions"` 请求体中。如果它与自动生成的请求键冲突,则以额外请求体为准;非原生 completions 路由之后仍会去除仅 OpenAI 使用的 `store`。
|
||||
- `params.chat_template_kwargs`:vLLM / OpenAI 兼容的聊天模板参数,会合并到顶层 `api: "openai-completions"` 请求体中。对于关闭 thinking 的 `vllm/nemotron-3-*`,OpenClaw 会自动发送 `enable_thinking: false` 和 `force_nonempty_content: true`;显式的 `chat_template_kwargs` 会覆盖这些默认值,而 `extra_body.chat_template_kwargs` 仍拥有最终优先级。
|
||||
- `embeddedHarness`:默认的底层嵌入式智能体运行时策略。未指定 runtime 时默认使用 OpenClaw Pi。使用 `runtime: "pi"` 可强制使用内置 PI harness,使用 `runtime: "auto"` 可让已注册插件 harness 接管其支持的模型,或使用已注册的 harness id,例如 `runtime: "codex"`。设置 `fallback: "none"` 可禁用自动回退到 PI。显式插件运行时(如 `codex`)默认是失败即关闭,除非你在同一覆盖范围中设置 `fallback: "pi"`。将模型引用保持为标准形式 `provider/model`;通过运行时配置而不是旧版 runtime provider 前缀来选择 Codex、Claude CLI、Gemini CLI 和其他执行后端。关于它与提供商 / 模型选择的区别,请参见 [Agent Runtimes](/zh-CN/concepts/agent-runtimes)。
|
||||
- 修改这些字段的配置写入器(例如 `/models set`、`/models set-image` 以及回退添加 / 删除命令)会保存为标准对象形式,并尽可能保留现有回退列表。
|
||||
- `maxConcurrent`:跨会话并行智能体运行的最大数量(每个会话本身仍然串行)。默认值:4。
|
||||
|
||||
### `agents.defaults.embeddedHarness`
|
||||
|
||||
`embeddedHarness` 用于控制由哪个底层执行器运行嵌入式智能体轮次。
|
||||
大多数部署应保留默认的 OpenClaw Pi 运行时。
|
||||
当某个受信任插件提供原生 harness 时再使用它,例如内置的
|
||||
`embeddedHarness` 控制哪个底层执行器运行嵌入式智能体轮次。
|
||||
大多数部署应保持默认的 OpenClaw Pi 运行时。
|
||||
当受信任的插件提供原生 harness 时可使用它,例如内置的
|
||||
Codex 应用服务器 harness。关于其心智模型,请参见
|
||||
[Agent Runtimes](/zh-CN/concepts/agent-runtimes)。
|
||||
|
||||
@ -390,14 +391,14 @@ Codex 应用服务器 harness。关于其心智模型,请参见
|
||||
}
|
||||
```
|
||||
|
||||
- `runtime`:`"auto"`、`"pi"`,或已注册的插件 harness id。内置的 Codex 插件注册为 `codex`。
|
||||
- `fallback`:`"pi"` 或 `"none"`。在 `runtime: "auto"` 下,若省略 `fallback`,默认值为 `"pi"`,这样旧配置在没有插件 harness 认领运行时仍可继续使用 PI。在显式插件运行时模式下,例如 `runtime: "codex"`,若省略 `fallback`,默认值为 `"none"`,这样缺失 harness 时会直接失败,而不是静默使用 PI。运行时覆盖不会从更广作用域继承 `fallback`;如果你确实希望保留这种兼容性回退,请在显式运行时旁边同时设置 `fallback: "pi"`。所选插件 harness 的失败始终会直接显示出来。
|
||||
- 环境变量覆盖:`OPENCLAW_AGENT_RUNTIME=<id|auto|pi>` 会覆盖 `runtime`;`OPENCLAW_AGENT_HARNESS_FALLBACK=pi|none` 会覆盖该进程的 `fallback`。
|
||||
- 对于仅使用 Codex 的部署,设置 `model: "openai/gpt-5.5"` 和 `embeddedHarness.runtime: "codex"`。你也可以显式设置 `embeddedHarness.fallback: "none"` 以提高可读性;这是显式插件运行时的默认值。
|
||||
- harness 的选择会在第一次嵌入式运行后按会话 id 固定。配置 / 环境变量变更只影响新的或已重置的会话,不影响现有 transcript。带有 transcript 历史但未记录固定值的旧会话会被视为固定到 PI。`/status` 会报告实际运行时,例如 `Runtime: OpenClaw Pi Default` 或 `Runtime: OpenAI Codex`。
|
||||
- `runtime`:`"auto"`、`"pi"` 或已注册的插件 harness id。内置 Codex 插件会注册 `codex`。
|
||||
- `fallback`:`"pi"` 或 `"none"`。在 `runtime: "auto"` 中,省略 `fallback` 时默认值为 `"pi"`,这样旧配置在没有插件 harness 接管运行时仍可继续使用 PI。在显式插件运行时模式下,例如 `runtime: "codex"`,省略 `fallback` 时默认值为 `"none"`,这样缺少 harness 时会直接失败,而不是静默使用 PI。运行时覆盖项不会从更广范围继承 fallback;当你确实想要这种兼容性回退时,请与显式 runtime 一起设置 `fallback: "pi"`。所选插件 harness 的失败始终会直接显示出来。
|
||||
- 环境变量覆盖:`OPENCLAW_AGENT_RUNTIME=<id|auto|pi>` 会覆盖 `runtime`;`OPENCLAW_AGENT_HARNESS_FALLBACK=pi|none` 会覆盖该进程的 fallback。
|
||||
- 对于仅使用 Codex 的部署,设置 `model: "openai/gpt-5.5"` 和 `embeddedHarness.runtime: "codex"`。你也可以显式设置 `embeddedHarness.fallback: "none"` 以增强可读性;对于显式插件运行时,这本就是默认值。
|
||||
- 在第一次嵌入式运行后,harness 选择会按会话 id 固定。配置 / 环境变量变更会影响新的或重置后的会话,不会影响现有转录。带有转录历史但没有记录固定值的旧会话会被视为固定到 PI。`/status` 会报告实际生效的运行时,例如 `Runtime: OpenClaw Pi Default` 或 `Runtime: OpenAI Codex`。
|
||||
- 这只控制嵌入式聊天 harness。媒体生成、视觉、PDF、音乐、视频和 TTS 仍使用它们各自的提供商 / 模型设置。
|
||||
|
||||
**内置别名简写**(仅在模型位于 `agents.defaults.models` 中时适用):
|
||||
**内置别名简写**(仅当模型位于 `agents.defaults.models` 中时适用):
|
||||
|
||||
| 别名 | 模型 |
|
||||
| ------------------- | ------------------------------------------ |
|
||||
@ -418,7 +419,7 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
|
||||
### `agents.defaults.cliBackends`
|
||||
|
||||
用于纯文本回退运行(无工具调用)的可选 CLI 后端。在 API 提供商失败时,可用作备用方案。
|
||||
用于纯文本回退运行(无工具调用)的可选 CLI 后端。在 API 提供商失败时,可作为备用方案。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -436,7 +437,7 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
sessionArg: "--session",
|
||||
sessionMode: "existing",
|
||||
systemPromptArg: "--system",
|
||||
// 或者当 CLI 接受提示文件参数时,使用 systemPromptFileArg。
|
||||
// 或者在 CLI 接受提示词文件标志时,使用 systemPromptFileArg。
|
||||
systemPromptWhen: "first",
|
||||
imageArg: "--image",
|
||||
imageMode: "repeat",
|
||||
@ -453,7 +454,7 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
|
||||
### `agents.defaults.systemPromptOverride`
|
||||
|
||||
用固定字符串替换整个由 OpenClaw 组装的系统提示。可在默认级别(`agents.defaults.systemPromptOverride`)设置,也可按智能体设置(`agents.list[].systemPromptOverride`)。按智能体设置的值优先;空值或仅包含空白的值会被忽略。适用于受控提示实验。
|
||||
用固定字符串替换整个由 OpenClaw 组装的系统提示词。可在默认级别(`agents.defaults.systemPromptOverride`)或按智能体设置(`agents.list[].systemPromptOverride`)。按智能体的值优先级更高;空值或仅包含空白字符的值会被忽略。适用于受控的提示词实验。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -467,7 +468,7 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
|
||||
### `agents.defaults.promptOverlays`
|
||||
|
||||
按模型家族应用、与提供商无关的提示覆盖层。GPT-5 系列模型 id 会在不同提供商之间获得共享的行为契约;`personality` 只控制友好交互风格这一层。
|
||||
按模型家族应用的、与提供商无关的提示词叠加层。GPT-5 家族模型 id 会在不同提供商之间获得共享的行为契约;`personality` 仅控制友好的交互风格层。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -483,13 +484,13 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
}
|
||||
```
|
||||
|
||||
- `"friendly"`(默认)和 `"on"` 会启用友好交互风格层。
|
||||
- `"off"` 只会禁用友好层;带标签的 GPT-5 行为契约仍然保持启用。
|
||||
- 当这个共享设置未设置时,仍会读取旧版的 `plugins.entries.openai.config.personality`。
|
||||
- `"friendly"`(默认)和 `"on"` 会启用友好的交互风格层。
|
||||
- `"off"` 仅禁用友好层;带标签的 GPT-5 行为契约仍会启用。
|
||||
- 当这个共享设置未设置时,仍会读取旧版 `plugins.entries.openai.config.personality`。
|
||||
|
||||
### `agents.defaults.heartbeat`
|
||||
|
||||
周期性心跳运行。
|
||||
周期性 Heartbeat 运行。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -499,14 +500,14 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
every: "30m", // 0m 表示禁用
|
||||
model: "openai/gpt-5.4-mini",
|
||||
includeReasoning: false,
|
||||
includeSystemPromptSection: true, // 默认值:true;false 会从系统提示中省略 Heartbeat 部分
|
||||
lightContext: false, // 默认值:false;true 只保留工作区引导文件中的 HEARTBEAT.md
|
||||
isolatedSession: false, // 默认值:false;true 会让每次心跳在全新会话中运行(无对话历史)
|
||||
includeSystemPromptSection: true, // 默认:true;false 会从系统提示词中省略 Heartbeat 部分
|
||||
lightContext: false, // 默认:false;true 仅保留工作区引导文件中的 HEARTBEAT.md
|
||||
isolatedSession: false, // 默认:false;true 会让每次 heartbeat 在全新会话中运行(无对话历史)
|
||||
session: "main",
|
||||
to: "+15555550123",
|
||||
directPolicy: "allow", // allow(默认)| block
|
||||
target: "none", // 默认:none | 可选值:last | whatsapp | telegram | discord | ...
|
||||
prompt: "如果存在,请读取 HEARTBEAT.md...",
|
||||
prompt: "Read HEARTBEAT.md if it exists...",
|
||||
ackMaxChars: 300,
|
||||
suppressToolErrorWarnings: false,
|
||||
timeoutSeconds: 45,
|
||||
@ -516,15 +517,15 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
}
|
||||
```
|
||||
|
||||
- `every`:时长字符串(ms/s/m/h)。默认值:`30m`(API 密钥认证)或 `1h`(OAuth 认证)。设为 `0m` 可禁用。
|
||||
- `includeSystemPromptSection`:为 false 时,会从系统提示中省略 Heartbeat 部分,并跳过将 `HEARTBEAT.md` 注入引导上下文。默认值:`true`。
|
||||
- `suppressToolErrorWarnings`:为 true 时,会在心跳运行期间抑制工具错误警告负载。
|
||||
- `timeoutSeconds`:在心跳智能体轮次被中止前允许的最长秒数。若留空,则使用 `agents.defaults.timeoutSeconds`。
|
||||
- `directPolicy`:直接 / 私信投递策略。`allow`(默认)允许直接目标投递。`block` 会阻止直接目标投递,并发出 `reason=dm-blocked`。
|
||||
- `lightContext`:为 true 时,心跳运行会使用轻量级引导上下文,并且只保留工作区引导文件中的 `HEARTBEAT.md`。
|
||||
- `isolatedSession`:为 true 时,每次心跳都会在一个没有既往对话历史的新会话中运行。其隔离模式与 cron `sessionTarget: "isolated"` 相同。可将每次心跳的 token 成本从约 100K 降低到约 2-5K token。
|
||||
- 按智能体设置:使用 `agents.list[].heartbeat`。当任一智能体定义了 `heartbeat` 时,**只有这些智能体** 会运行心跳。
|
||||
- 心跳会运行完整的智能体轮次——间隔越短,消耗的 token 越多。
|
||||
- `every`:时长字符串(ms/s/m/h)。默认值:`30m`(API key 凭证)或 `1h`(OAuth 凭证)。设为 `0m` 可禁用。
|
||||
- `includeSystemPromptSection`:设为 false 时,会从系统提示词中省略 Heartbeat 部分,并跳过将 `HEARTBEAT.md` 注入引导上下文。默认值:`true`。
|
||||
- `suppressToolErrorWarnings`:设为 true 时,会在 heartbeat 运行期间抑制工具错误警告负载。
|
||||
- `timeoutSeconds`:heartbeat 智能体轮次在被中止前允许的最长时间(秒)。留空则使用 `agents.defaults.timeoutSeconds`。
|
||||
- `directPolicy`:直接 / 私信投递策略。`allow`(默认)允许投递到直接目标。`block` 会阻止投递到直接目标,并发出 `reason=dm-blocked`。
|
||||
- `lightContext`:设为 true 时,heartbeat 运行使用轻量引导上下文,并且仅保留工作区引导文件中的 `HEARTBEAT.md`。
|
||||
- `isolatedSession`:设为 true 时,每次 heartbeat 都会在没有任何先前对话历史的全新会话中运行。与 cron `sessionTarget: "isolated"` 使用相同的隔离模式。可将每次 heartbeat 的 token 成本从约 100K 降低到约 2-5K token。
|
||||
- 按智能体配置:设置 `agents.list[].heartbeat`。当任一智能体定义了 `heartbeat` 时,**只有这些智能体**会运行 heartbeat。
|
||||
- Heartbeat 会运行完整的智能体轮次——间隔越短,消耗的 token 越多。
|
||||
|
||||
### `agents.defaults.compaction`
|
||||
|
||||
@ -534,21 +535,21 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
defaults: {
|
||||
compaction: {
|
||||
mode: "safeguard", // default | safeguard
|
||||
provider: "my-provider", // 已注册压缩提供商插件的 id(可选)
|
||||
provider: "my-provider", // 已注册 compaction 提供商插件的 id(可选)
|
||||
timeoutSeconds: 900,
|
||||
reserveTokensFloor: 24000,
|
||||
keepRecentTokens: 50000,
|
||||
identifierPolicy: "strict", // strict | off | custom
|
||||
identifierInstructions: "精确保留部署 ID、工单 ID 和 host:port 对。", // 当 identifierPolicy=custom 时使用
|
||||
identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // 当 identifierPolicy=custom 时使用
|
||||
qualityGuard: { enabled: true, maxRetries: 1 },
|
||||
postCompactionSections: ["Session Startup", "Red Lines"], // [] 表示禁用重新注入
|
||||
model: "openrouter/anthropic/claude-sonnet-4-6", // 可选,仅用于压缩的模型覆盖
|
||||
notifyUser: true, // 在压缩开始和完成时发送简短通知(默认:false)
|
||||
model: "openrouter/anthropic/claude-sonnet-4-6", // 可选,仅用于 compaction 的模型覆盖
|
||||
notifyUser: true, // 在 compaction 开始和完成时发送简短通知(默认:false)
|
||||
memoryFlush: {
|
||||
enabled: true,
|
||||
softThresholdTokens: 6000,
|
||||
systemPrompt: "会话即将压缩。请现在存储持久记忆。",
|
||||
prompt: "将任何持久笔记写入 memory/YYYY-MM-DD.md;如果没有需要存储的内容,请精确回复静默令牌 NO_REPLY。",
|
||||
systemPrompt: "Session nearing compaction. Store durable memories now.",
|
||||
prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with the exact silent token NO_REPLY if nothing to store.",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -556,21 +557,21 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
}
|
||||
```
|
||||
|
||||
- `mode`:`default` 或 `safeguard`(对长历史进行分块摘要)。参见 [压缩](/zh-CN/concepts/compaction)。
|
||||
- `provider`:已注册压缩提供商插件的 id。设置后,将调用该提供商的 `summarize()`,而不是内置的 LLM 摘要。失败时回退到内置方式。设置提供商会强制启用 `mode: "safeguard"`。参见 [压缩](/zh-CN/concepts/compaction)。
|
||||
- `timeoutSeconds`:OpenClaw 中止单次压缩操作前允许的最大秒数。默认值:`900`。
|
||||
- `keepRecentTokens`:Pi 切分点预算,用于将最近的 transcript 尾部按原样保留。手动 `/compact` 在显式设置时会遵循该值;否则手动压缩就是一个硬检查点。
|
||||
- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在压缩摘要期间预置内置的不透明标识符保留指导。
|
||||
- `mode`:`default` 或 `safeguard`(对长历史进行分块摘要)。参见 [Compaction](/zh-CN/concepts/compaction)。
|
||||
- `provider`:已注册 compaction 提供商插件的 id。设置后,将调用该提供商的 `summarize()`,而不是使用内置 LLM 摘要。失败时会回退到内置实现。设置提供商会强制启用 `mode: "safeguard"`。参见 [Compaction](/zh-CN/concepts/compaction)。
|
||||
- `timeoutSeconds`:OpenClaw 中止单次 compaction 操作前允许的最长秒数。默认值:`900`。
|
||||
- `keepRecentTokens`:Pi 截断点预算,用于将最近的转录尾部按原样保留。手动 `/compact` 在显式设置时会遵循此值;否则手动 compaction 是硬检查点。
|
||||
- `identifierPolicy`:`strict`(默认)、`off` 或 `custom`。`strict` 会在 compaction 摘要期间预先添加内置的、不透明标识符保留指导。
|
||||
- `identifierInstructions`:当 `identifierPolicy=custom` 时使用的可选自定义标识符保留文本。
|
||||
- `qualityGuard`:针对 safeguard 摘要的输出格式错误重试检查。在 safeguard 模式下默认启用;将 `enabled: false` 设为 false 可跳过审计。
|
||||
- `postCompactionSections`:压缩后重新注入的可选 `AGENTS.md` H2/H3 章节名称。默认值为 `["Session Startup", "Red Lines"]`;设为 `[]` 可禁用重新注入。当未设置,或显式设置为这组默认值时,也接受旧版的 `Every Session` / `Safety` 标题作为兼容性回退。
|
||||
- `model`:可选的仅用于压缩摘要的 `provider/model-id` 覆盖。适用于主会话保留某个模型,而压缩摘要应改用另一个模型的场景;未设置时,压缩会使用会话的主模型。
|
||||
- `notifyUser`:为 `true` 时,在压缩开始和完成时向用户发送简短通知(例如“正在压缩上下文...”和“压缩完成”)。默认禁用,以保持压缩过程静默。
|
||||
- `memoryFlush`:在自动压缩之前执行的静默智能体轮次,用于存储持久记忆。工作区为只读时会跳过。
|
||||
- `qualityGuard`:用于 safeguard 摘要的输出格式错误重试检查。在 safeguard 模式下默认启用;设为 `enabled: false` 可跳过审计。
|
||||
- `postCompactionSections`:compaction 后要重新注入的可选 `AGENTS.md` H2/H3 章节名。默认值为 `["Session Startup", "Red Lines"]`;设为 `[]` 可禁用重新注入。当未设置,或显式设置为这对默认值时,也接受旧版 `Every Session` / `Safety` 标题作为兼容回退。
|
||||
- `model`:可选的 `provider/model-id` 覆盖项,仅用于 compaction 摘要。当主会话应保持一个模型,而 compaction 摘要应使用另一个模型时,可使用此项;未设置时,compaction 使用会话的主模型。
|
||||
- `notifyUser`:设为 `true` 时,会在 compaction 开始和完成时向用户发送简短通知(例如,“Compacting context...” 和 “Compaction complete”)。默认禁用,以保持 compaction 静默。
|
||||
- `memoryFlush`:在自动 compaction 前运行的静默智能体轮次,用于存储持久 memory。工作区为只读时会跳过。
|
||||
|
||||
### `agents.defaults.contextPruning`
|
||||
|
||||
在发送给 LLM 之前,从内存上下文中修剪**旧的工具结果**。**不会**修改磁盘上的会话历史。
|
||||
在将内容发送给 LLM 之前,从内存上下文中清理**旧工具结果**。**不会**修改磁盘上的会话历史。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -584,7 +585,7 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
hardClearRatio: 0.5,
|
||||
minPrunableToolChars: 50000,
|
||||
softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 },
|
||||
hardClear: { enabled: true, placeholder: "[旧工具结果内容已清除]" },
|
||||
hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" },
|
||||
tools: { deny: ["browser", "canvas"] },
|
||||
},
|
||||
},
|
||||
@ -594,23 +595,23 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
|
||||
<Accordion title="`cache-ttl` 模式行为">
|
||||
|
||||
- `mode: "cache-ttl"` 会启用修剪流程。
|
||||
- `ttl` 控制下次允许再次运行修剪的时间间隔(自上次缓存触碰之后)。
|
||||
- 修剪会先对过大的工具结果执行软修剪,如仍有需要,再对更旧的工具结果执行硬清除。
|
||||
- `mode: "cache-ttl"` 会启用清理流程。
|
||||
- `ttl` 控制在上次缓存触达后,多久才能再次运行清理。
|
||||
- 清理会先对过大的工具结果进行软裁剪,必要时再对更旧的工具结果进行硬清除。
|
||||
|
||||
**软修剪**会保留开头和结尾,并在中间插入 `...`。
|
||||
**软裁剪**会保留开头和结尾,并在中间插入 `...`。
|
||||
|
||||
**硬清除**会用占位符替换整个工具结果。
|
||||
|
||||
注意事项:
|
||||
说明:
|
||||
|
||||
- 图像块永远不会被修剪 / 清除。
|
||||
- 比例基于字符数(近似值),不是精确 token 数。
|
||||
- 如果 assistant 消息数量少于 `keepLastAssistants`,则跳过修剪。
|
||||
- 图像块永远不会被裁剪 / 清除。
|
||||
- 这些比例基于字符数(近似),不是精确 token 数。
|
||||
- 如果 assistant 消息少于 `keepLastAssistants` 条,则跳过清理。
|
||||
|
||||
</Accordion>
|
||||
|
||||
行为详情参见 [会话修剪](/zh-CN/concepts/session-pruning)。
|
||||
关于行为细节,请参见 [Session Pruning](/zh-CN/concepts/session-pruning)。
|
||||
|
||||
### 分块流式传输
|
||||
|
||||
@ -628,13 +629,13 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
}
|
||||
```
|
||||
|
||||
- 非 Telegram 渠道需要显式设置 `*.blockStreaming: true` 才会启用分块回复。
|
||||
- 渠道覆盖:`channels.<channel>.blockStreamingCoalesce`(以及按账号区分的变体)。Signal / Slack / Discord / Google Chat 默认 `minChars: 1500`。
|
||||
- `humanDelay`:分块回复之间的随机暂停。`natural` = 800–2500 ms。按智能体覆盖:`agents.list[].humanDelay`。
|
||||
- 非 Telegram 渠道需要显式设置 `*.blockStreaming: true` 才能启用分块回复。
|
||||
- 渠道覆盖项:`channels.<channel>.blockStreamingCoalesce`(以及按账号变体)。Signal / Slack / Discord / Google Chat 默认 `minChars: 1500`。
|
||||
- `humanDelay`:分块回复之间的随机暂停。`natural` = 800–2500 ms。按智能体覆盖项:`agents.list[].humanDelay`。
|
||||
|
||||
行为和分块详情参见 [流式传输](/zh-CN/concepts/streaming)。
|
||||
关于行为和分块细节,请参见 [Streaming](/zh-CN/concepts/streaming)。
|
||||
|
||||
### 输入中指示器
|
||||
### 正在输入指示器
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -647,16 +648,16 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
}
|
||||
```
|
||||
|
||||
- 默认值:直接聊天 / 提及时为 `instant`,未被提及的群聊中为 `message`。
|
||||
- 按会话覆盖:`session.typingMode`、`session.typingIntervalSeconds`。
|
||||
- 默认值:直接聊天 / 被提及时使用 `instant`,未被提及的群聊使用 `message`。
|
||||
- 按会话覆盖项:`session.typingMode`、`session.typingIntervalSeconds`。
|
||||
|
||||
参见 [输入中指示器](/zh-CN/concepts/typing-indicators)。
|
||||
参见 [Typing Indicators](/zh-CN/concepts/typing-indicators)。
|
||||
|
||||
<a id="agentsdefaultssandbox"></a>
|
||||
|
||||
### `agents.defaults.sandbox`
|
||||
|
||||
用于嵌入式智能体的可选沙箱隔离。完整指南请参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。
|
||||
嵌入式智能体的可选沙箱隔离。完整指南请参见 [沙箱隔离](/zh-CN/gateway/sandboxing)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -756,7 +757,7 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
**后端:**
|
||||
|
||||
- `docker`:本地 Docker 运行时(默认)
|
||||
- `ssh`:通用 SSH 支持的远程运行时
|
||||
- `ssh`:通用的基于 SSH 的远程运行时
|
||||
- `openshell`:OpenShell 运行时
|
||||
|
||||
当选择 `backend: "openshell"` 时,运行时特定设置会移动到
|
||||
@ -766,37 +767,37 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
|
||||
- `target`:`user@host[:port]` 形式的 SSH 目标
|
||||
- `command`:SSH 客户端命令(默认:`ssh`)
|
||||
- `workspaceRoot`:用于按作用域工作区的远程绝对根路径
|
||||
- `workspaceRoot`:用于按 scope 工作区的远程绝对根目录
|
||||
- `identityFile` / `certificateFile` / `knownHostsFile`:传递给 OpenSSH 的现有本地文件
|
||||
- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其写入临时文件
|
||||
- `identityData` / `certificateData` / `knownHostsData`:内联内容或 SecretRef,OpenClaw 会在运行时将其实体化为临时文件
|
||||
- `strictHostKeyChecking` / `updateHostKeys`:OpenSSH 主机密钥策略开关
|
||||
|
||||
**SSH 认证优先级:**
|
||||
**SSH 凭证优先级:**
|
||||
|
||||
- `identityData` 优先于 `identityFile`
|
||||
- `certificateData` 优先于 `certificateFile`
|
||||
- `knownHostsData` 优先于 `knownHostsFile`
|
||||
- 由 SecretRef 支持的 `*Data` 值会在沙箱会话开始前,从当前活动的 secrets 运行时快照中解析
|
||||
- 基于 SecretRef 的 `*Data` 值会在沙箱会话开始前,从当前激活的 secrets 运行时快照中解析
|
||||
|
||||
**SSH 后端行为:**
|
||||
|
||||
- 在创建或重新创建后,只对远程工作区执行一次初始化植入
|
||||
- 之后保持远程 SSH 工作区为规范版本
|
||||
- 在创建或重新创建后,会先对远程工作区进行一次初始化
|
||||
- 然后保持远程 SSH 工作区为标准来源
|
||||
- 通过 SSH 路由 `exec`、文件工具和媒体路径
|
||||
- 不会自动将远程更改同步回主机
|
||||
- 不支持沙箱浏览器容器
|
||||
|
||||
**工作区访问:**
|
||||
|
||||
- `none`:位于 `~/.openclaw/sandboxes` 下、按作用域划分的沙箱工作区
|
||||
- `none`:位于 `~/.openclaw/sandboxes` 下、按 scope 划分的沙箱工作区
|
||||
- `ro`:沙箱工作区位于 `/workspace`,智能体工作区以只读方式挂载到 `/agent`
|
||||
- `rw`:智能体工作区以读写方式挂载到 `/workspace`
|
||||
|
||||
**作用域:**
|
||||
**Scope:**
|
||||
|
||||
- `session`:每个会话一个容器 + 工作区
|
||||
- `agent`:每个智能体一个容器 + 工作区(默认)
|
||||
- `shared`:共享容器和工作区(无跨会话隔离)
|
||||
- `shared`:共享容器和工作区(不进行跨会话隔离)
|
||||
|
||||
**OpenShell 插件配置:**
|
||||
|
||||
@ -813,7 +814,7 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
remoteAgentWorkspaceDir: "/agent",
|
||||
gateway: "lab", // 可选
|
||||
gatewayEndpoint: "https://lab.example", // 可选
|
||||
policy: "strict", // 可选的 OpenShell 策略 id
|
||||
policy: "strict", // 可选的 OpenShell policy id
|
||||
providers: ["openai"], // 可选
|
||||
autoProviders: true,
|
||||
timeoutSeconds: 120,
|
||||
@ -826,29 +827,29 @@ Anthropic Claude 4.6 模型在未显式设置 thinking 级别时,默认使用
|
||||
|
||||
**OpenShell 模式:**
|
||||
|
||||
- `mirror`:在执行前将本地内容植入远程,执行后再同步回来;本地工作区保持为规范版本
|
||||
- `remote`:在创建沙箱时只向远程植入一次,之后保持远程工作区为规范版本
|
||||
- `mirror`:在执行前将本地内容初始化到远程,执行后再同步回来;本地工作区保持为标准来源
|
||||
- `remote`:在创建沙箱时仅初始化一次远程内容,此后保持远程工作区为标准来源
|
||||
|
||||
在 `remote` 模式下,主机上在 OpenClaw 外部进行的本地编辑,在植入步骤之后不会自动同步到沙箱中。
|
||||
传输方式是通过 SSH 进入 OpenShell 沙箱,但沙箱生命周期以及可选的镜像同步由插件负责。
|
||||
在 `remote` 模式下,在 OpenClaw 外部于主机本地所做的编辑,在初始化步骤之后不会自动同步到沙箱中。
|
||||
传输方式是通过 SSH 进入 OpenShell 沙箱,但插件自身负责沙箱生命周期和可选的镜像同步。
|
||||
|
||||
**`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。需要网络出口、可写根文件系统和 root 用户。
|
||||
**`setupCommand`** 会在容器创建后运行一次(通过 `sh -lc`)。它需要网络出口、可写根文件系统以及 root 用户。
|
||||
|
||||
**容器默认使用 `network: "none"`** —— 如果智能体需要出站访问,请设为 `"bridge"`(或自定义 bridge 网络)。
|
||||
**容器默认使用 `network: "none"`**——如果智能体需要出站访问,请设置为 `"bridge"`(或自定义 bridge 网络)。
|
||||
`"host"` 会被阻止。默认情况下,`"container:<id>"` 也会被阻止,除非你显式设置
|
||||
`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(紧急破例开关)。
|
||||
`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(破窗处理)。
|
||||
|
||||
**入站附件** 会暂存到活动工作区中的 `media/inbound/*`。
|
||||
**入站附件** 会被临时存放到活动工作区中的 `media/inbound/*`。
|
||||
|
||||
**`docker.binds`** 会挂载额外的主机目录;全局和按智能体的绑定会合并。
|
||||
**`docker.binds`** 会挂载额外的主机目录;全局和按智能体的 binds 会合并。
|
||||
|
||||
**沙箱隔离浏览器**(`sandbox.browser.enabled`):在容器中运行 Chromium + CDP。noVNC URL 会注入到系统提示中。不需要在 `openclaw.json` 中启用 `browser.enabled`。
|
||||
**沙箱隔离浏览器**(`sandbox.browser.enabled`):在容器中运行 Chromium + CDP。noVNC URL 会注入到系统提示词中。不需要在 `openclaw.json` 中启用 `browser.enabled`。
|
||||
noVNC 观察者访问默认使用 VNC 认证,OpenClaw 会发出一个短期有效的 token URL(而不是在共享 URL 中暴露密码)。
|
||||
|
||||
- `allowHostControl: false`(默认)会阻止沙箱隔离会话以主机浏览器为目标。
|
||||
- `network` 默认是 `openclaw-sandbox-browser`(专用 bridge 网络)。只有在你明确希望使用全局 bridge 连接性时,才设为 `bridge`。
|
||||
- `cdpSourceRange` 可选地在容器边界将 CDP 入站限制到某个 CIDR 范围(例如 `172.21.0.1/32`)。
|
||||
- `sandbox.browser.binds` 仅将额外的主机目录挂载到沙箱浏览器容器中。设置后(包括 `[]`),它会替代浏览器容器的 `docker.binds`。
|
||||
- `allowHostControl: false`(默认)会阻止沙箱隔离会话将目标指向主机浏览器。
|
||||
- `network` 默认为 `openclaw-sandbox-browser`(专用 bridge 网络)。仅当你明确需要全局 bridge 连通性时,才设置为 `bridge`。
|
||||
- `cdpSourceRange` 可选择将容器边界处的 CDP 入站限制为某个 CIDR 范围(例如 `172.21.0.1/32`)。
|
||||
- `sandbox.browser.binds` 仅将额外主机目录挂载到沙箱浏览器容器中。设置后(包括 `[]`),它会替代浏览器容器的 `docker.binds`。
|
||||
- 启动默认值定义在 `scripts/sandbox-browser-entrypoint.sh` 中,并针对容器主机进行了调优:
|
||||
- `--remote-debugging-address=127.0.0.1`
|
||||
- `--remote-debugging-port=<derived from OPENCLAW_BROWSER_CDP_PORT>`
|
||||
@ -868,15 +869,15 @@ noVNC 观察者访问默认使用 VNC 认证,OpenClaw 会发出一个短期有
|
||||
- `--metrics-recording-only`
|
||||
- `--disable-extensions`(默认启用)
|
||||
- `--disable-3d-apis`、`--disable-software-rasterizer` 和 `--disable-gpu`
|
||||
默认启用;如果 WebGL / 3D 使用场景需要,可通过
|
||||
`OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 禁用这些默认标志。
|
||||
- `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 会重新启用扩展,如果你的工作流
|
||||
依赖它们。
|
||||
默认启用;如果 WebGL / 3D 使用场景需要它们,可通过
|
||||
`OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0` 禁用这些标志。
|
||||
- 如果你的工作流依赖扩展,可使用
|
||||
`OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0` 重新启用扩展。
|
||||
- `--renderer-process-limit=2` 可通过
|
||||
`OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>` 修改;设为 `0` 可使用 Chromium 的
|
||||
`OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N>` 更改;设为 `0` 时使用 Chromium 的
|
||||
默认进程限制。
|
||||
- 以及当启用 `noSandbox` 时附加 `--no-sandbox`。
|
||||
- 这些默认值是容器镜像的基线;如果要修改容器默认值,请使用带有自定义
|
||||
- 此外,当启用 `noSandbox` 时,还会加上 `--no-sandbox`。
|
||||
- 这些默认值是容器镜像的基线;如需更改容器默认行为,请使用带有自定义
|
||||
entrypoint 的自定义浏览器镜像。
|
||||
|
||||
</Accordion>
|
||||
@ -890,14 +891,9 @@ scripts/sandbox-setup.sh # 主沙箱镜像
|
||||
scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
```
|
||||
|
||||
### `agents.list`(按智能体覆盖)
|
||||
### `agents.list`(按智能体覆盖项)
|
||||
|
||||
使用 `agents.list[].tts` 为某个智能体设置其专属的 TTS 提供商、语音、模型、
|
||||
风格或自动 TTS 模式。该智能体配置块会在全局
|
||||
`messages.tts` 之上进行深度合并,因此共享凭据可以保留在一个地方,而各个
|
||||
智能体只需覆盖自己所需的语音或提供商字段。当前智能体的
|
||||
覆盖会应用于自动语音回复、`/tts audio`、`/tts status` 以及
|
||||
`tts` 智能体工具。有关提供商示例和优先级,请参见 [文本转语音](/zh-CN/tools/tts#per-agent-voice-overrides)。
|
||||
使用 `agents.list[].tts` 可为某个智能体指定它自己的 TTS 提供商、语音、模型、风格或自动 TTS 模式。智能体块会在全局 `messages.tts` 之上进行深度合并,因此共享凭证可以保留在一个位置,而各个智能体只覆盖它们需要的语音或提供商字段。当前智能体的覆盖项会应用于自动语音回复、`/tts audio`、`/tts status` 和 `tts` 智能体工具。关于提供商示例和优先级,请参见 [Text-to-speech](/zh-CN/tools/tts#per-agent-voice-overrides)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -910,9 +906,9 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
workspace: "~/.openclaw/workspace",
|
||||
agentDir: "~/.openclaw/agents/main/agent",
|
||||
model: "anthropic/claude-opus-4-6", // 或 { primary, fallbacks }
|
||||
thinkingDefault: "high", // 按智能体覆盖的默认 thinking 级别
|
||||
reasoningDefault: "on", // 按智能体覆盖的默认 reasoning 可见性
|
||||
fastModeDefault: false, // 按智能体覆盖的默认快速模式
|
||||
thinkingDefault: "high", // 按智能体覆盖 thinking 级别
|
||||
reasoningDefault: "on", // 按智能体覆盖 reasoning 可见性
|
||||
fastModeDefault: false, // 按智能体覆盖快速模式
|
||||
embeddedHarness: { runtime: "auto", fallback: "pi" },
|
||||
params: { cacheRetention: "none" }, // 按键覆盖匹配的 defaults.models params
|
||||
tts: {
|
||||
@ -923,7 +919,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
skills: ["docs-search"], // 设置后会替换 agents.defaults.skills
|
||||
identity: {
|
||||
name: "Samantha",
|
||||
theme: "乐于助人的树懒",
|
||||
theme: "helpful sloth",
|
||||
emoji: "🦥",
|
||||
avatar: "avatars/samantha.png",
|
||||
},
|
||||
@ -952,27 +948,27 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
```
|
||||
|
||||
- `id`:稳定的智能体 id(必填)。
|
||||
- `default`:若设置了多个,则第一个生效(会记录警告)。如果都未设置,则列表中的第一个条目为默认智能体。
|
||||
- `model`:字符串形式只覆盖 `primary`;对象形式 `{ primary, fallbacks }` 同时覆盖两者(`[]` 会禁用全局回退)。仅覆盖 `primary` 的 cron 作业仍会继承默认回退,除非你设置 `fallbacks: []`。
|
||||
- `params`:按智能体设置的流参数,会合并到 `agents.defaults.models` 中选定模型条目之上。用于智能体特定的覆盖,例如 `cacheRetention`、`temperature` 或 `maxTokens`,而无需复制整个模型目录。
|
||||
- `tts`:可选的按智能体文本转语音覆盖。该配置块会在 `messages.tts` 之上做深度合并,因此共享的提供商凭据和回退策略应保留在 `messages.tts` 中,而这里只设置角色特定值,例如提供商、语音、模型、风格或自动模式。
|
||||
- `skills`:可选的按智能体 Skills 允许列表。如果省略,当设置了 `agents.defaults.skills` 时,智能体会继承它;显式列表会替换默认值而不是合并,`[]` 表示没有 Skills。
|
||||
- `thinkingDefault`:可选的按智能体默认 thinking 级别(`off | minimal | low | medium | high | xhigh | adaptive | max`)。当未设置按消息或按会话覆盖时,它会覆盖此智能体的 `agents.defaults.thinkingDefault`。所选提供商 / 模型配置文件决定哪些值有效;对于 Google Gemini,`adaptive` 会保留由提供商控制的动态 thinking(在 Gemini 3 / 3.1 上省略 `thinkingLevel`,在 Gemini 2.5 上使用 `thinkingBudget: -1`)。
|
||||
- `reasoningDefault`:可选的按智能体默认 reasoning 可见性(`on | off | stream`)。当未设置按消息或按会话的 reasoning 覆盖时生效。
|
||||
- `fastModeDefault`:可选的按智能体默认快速模式(`true | false`)。当未设置按消息或按会话的快速模式覆盖时生效。
|
||||
- `embeddedHarness`:可选的按智能体低层 harness 策略覆盖。使用 `{ runtime: "codex" }` 可让某个智能体仅使用 Codex,而其他智能体保持默认的 `auto` 模式 PI 回退。
|
||||
- `default`:如果设置了多个,则以第一个为准(会记录警告)。如果一个都没设置,则列表中的第一个为默认值。
|
||||
- `model`:字符串形式只覆盖 `primary`;对象形式 `{ primary, fallbacks }` 会同时覆盖两者(`[]` 会禁用全局回退)。仅覆盖 `primary` 的 cron 作业仍会继承默认回退,除非你设置 `fallbacks: []`。
|
||||
- `params`:按智能体范围的流参数,会合并到 `agents.defaults.models` 中所选模型条目之上。用它来实现智能体特定的覆盖,例如 `cacheRetention`、`temperature` 或 `maxTokens`,而无需复制整个模型目录。
|
||||
- `tts`:可选的按智能体文本转语音覆盖项。该块会在 `messages.tts` 之上深度合并,因此将共享提供商凭证和回退策略放在 `messages.tts` 中,而这里只设置提供商、语音、模型、风格或自动模式等角色特定值。
|
||||
- `skills`:可选的按智能体 Skills 允许列表。如果省略,则当设置了 `agents.defaults.skills` 时,该智能体会继承它;显式列表会替换默认值而不是合并,`[]` 表示不启用任何 Skills。
|
||||
- `thinkingDefault`:可选的按智能体默认 thinking 级别(`off | minimal | low | medium | high | xhigh | adaptive | max`)。当未设置按消息或按会话覆盖时,它会覆盖该智能体的 `agents.defaults.thinkingDefault`。所选提供商 / 模型配置决定了哪些值有效;对于 Google Gemini,`adaptive` 会保留由提供商控制的动态 thinking(Gemini 3 / 3.1 上省略 `thinkingLevel`,Gemini 2.5 上使用 `thinkingBudget: -1`)。
|
||||
- `reasoningDefault`:可选的按智能体默认 reasoning 可见性(`on | off | stream`)。当未设置按消息或按会话 reasoning 覆盖时应用。
|
||||
- `fastModeDefault`:可选的按智能体默认快速模式(`true | false`)。当未设置按消息或按会话快速模式覆盖时应用。
|
||||
- `embeddedHarness`:可选的按智能体底层 harness 策略覆盖项。使用 `{ runtime: "codex" }` 可让某个智能体仅使用 Codex,而其他智能体继续保留 `auto` 模式下默认的 PI 回退。
|
||||
- `runtime`:可选的按智能体运行时描述符。当智能体应默认使用 ACP harness 会话时,使用 `type: "acp"` 以及 `runtime.acp` 默认值(`agent`、`backend`、`mode`、`cwd`)。
|
||||
- `identity.avatar`:工作区相对路径、`http(s)` URL 或 `data:` URI。
|
||||
- `identity.avatar`:相对于工作区的路径、`http(s)` URL 或 `data:` URI。
|
||||
- `identity` 会派生默认值:`ackReaction` 来自 `emoji`,`mentionPatterns` 来自 `name` / `emoji`。
|
||||
- `subagents.allowAgents`:`sessions_spawn` 可用的智能体 id 允许列表(`["*"]` = 任意;默认:仅当前智能体)。
|
||||
- 沙箱继承保护:如果请求方会话处于沙箱隔离状态,`sessions_spawn` 会拒绝那些将以非沙箱方式运行的目标。
|
||||
- `subagents.requireAgentId`:为 true 时,阻止省略 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置档;默认:false)。
|
||||
- `subagents.allowAgents`:`sessions_spawn` 可用的智能体 id 允许列表(`["*"]` = 任意;默认:仅同一智能体)。
|
||||
- 沙箱继承保护:如果请求方会话处于沙箱隔离中,`sessions_spawn` 会拒绝那些将以非沙箱方式运行的目标。
|
||||
- `subagents.requireAgentId`:设为 true 时,阻止未提供 `agentId` 的 `sessions_spawn` 调用(强制显式选择配置;默认:false)。
|
||||
|
||||
---
|
||||
|
||||
## 多智能体路由
|
||||
|
||||
在一个 Gateway 网关中运行多个相互隔离的智能体。参见 [多智能体](/zh-CN/concepts/multi-agent)。
|
||||
在一个 Gateway 网关中运行多个彼此隔离的智能体。参见 [Multi-Agent](/zh-CN/concepts/multi-agent)。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -991,29 +987,29 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
### 绑定匹配字段
|
||||
|
||||
- `type`(可选):普通路由使用 `route`(缺省时默认也是 route),持久 ACP 对话绑定使用 `acp`。
|
||||
- `type`(可选):普通路由使用 `route`(缺失时默认就是 route),持久 ACP 对话绑定使用 `acp`。
|
||||
- `match.channel`(必填)
|
||||
- `match.accountId`(可选;`*` = 任意账号;省略 = 默认账号)
|
||||
- `match.peer`(可选;`{ kind: direct|group|channel, id }`)
|
||||
- `match.guildId` / `match.teamId`(可选;渠道特定)
|
||||
- `acp`(可选;仅适用于 `type: "acp"`):`{ mode, label, cwd, backend }`
|
||||
- `match.guildId` / `match.teamId`(可选;特定于渠道)
|
||||
- `acp`(可选;仅用于 `type: "acp"`):`{ mode, label, cwd, backend }`
|
||||
|
||||
**确定性匹配顺序:**
|
||||
**确定性的匹配顺序:**
|
||||
|
||||
1. `match.peer`
|
||||
2. `match.guildId`
|
||||
3. `match.teamId`
|
||||
4. `match.accountId`(精确匹配,无 peer / guild / team)
|
||||
5. `match.accountId: "*"`(渠道范围)
|
||||
4. `match.accountId`(精确匹配,不含 peer / guild / team)
|
||||
5. `match.accountId: "*"`(整个渠道范围)
|
||||
6. 默认智能体
|
||||
|
||||
在每一层级内,第一个匹配的 `bindings` 条目生效。
|
||||
在每一层级中,第一个匹配的 `bindings` 条目获胜。
|
||||
|
||||
对于 `type: "acp"` 条目,OpenClaw 会按精确会话身份(`match.channel` + account + `match.peer.id`)解析,不使用上面的 route 绑定层级顺序。
|
||||
对于 `type: "acp"` 条目,OpenClaw 会按精确的会话身份(`match.channel` + account + `match.peer.id`)进行解析,不使用上面的 route 绑定层级顺序。
|
||||
|
||||
### 按智能体划分的访问配置档
|
||||
### 按智能体划分的访问配置
|
||||
|
||||
<Accordion title="完全访问(无沙箱隔离)">
|
||||
<Accordion title="完全访问(无沙箱)">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1060,7 +1056,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="无文件系统访问(仅消息传递)">
|
||||
<Accordion title="无文件系统访问(仅消息)">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1106,7 +1102,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
</Accordion>
|
||||
|
||||
有关优先级详情,请参见 [多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。
|
||||
关于优先级细节,请参见 [多智能体沙箱隔离与工具](/zh-CN/tools/multi-agent-sandbox-tools)。
|
||||
|
||||
---
|
||||
|
||||
@ -1132,7 +1128,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
},
|
||||
resetTriggers: ["/new", "/reset"],
|
||||
store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
|
||||
parentForkMaxTokens: 100000, // 超过此 token 数时跳过父线程分叉(0 表示禁用)
|
||||
parentForkMaxTokens: 100000, // 超过此 token 数则跳过父线程分叉(0 表示禁用)
|
||||
maintenance: {
|
||||
mode: "warn", // warn | enforce
|
||||
pruneAfter: "30d",
|
||||
@ -1144,7 +1140,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
},
|
||||
threadBindings: {
|
||||
enabled: true,
|
||||
idleHours: 24, // 默认按小时计算的不活跃自动取消聚焦时长(`0` 表示禁用)
|
||||
idleHours: 24, // 默认按小时计算的不活动自动失焦(`0` 表示禁用)
|
||||
maxAgeHours: 0, // 默认按小时计算的硬性最大时长(`0` 表示禁用)
|
||||
},
|
||||
mainKey: "main", // 旧版字段(运行时始终使用 "main")
|
||||
@ -1159,35 +1155,35 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
<Accordion title="会话字段详情">
|
||||
|
||||
- **`scope`**:群聊上下文的基础会话分组策略。
|
||||
- `per-sender`(默认):在一个渠道上下文中,每个发送者拥有独立的会话。
|
||||
- `global`:一个渠道上下文中的所有参与者共享同一个会话(仅在有意共享上下文时使用)。
|
||||
- **`dmScope`**:私信的分组方式。
|
||||
- **`scope`**:群聊上下文中的基础会话分组策略。
|
||||
- `per-sender`(默认):在某个渠道上下文中,每个发送者都有独立的会话。
|
||||
- `global`:某个渠道上下文中的所有参与者共享同一个会话(仅在确实需要共享上下文时使用)。
|
||||
- **`dmScope`**:私信如何分组。
|
||||
- `main`:所有私信共享主会话。
|
||||
- `per-peer`:按发送者 id 跨渠道隔离。
|
||||
- `per-channel-peer`:按渠道 + 发送者隔离(推荐用于多用户收件箱)。
|
||||
- `per-account-channel-peer`:按账号 + 渠道 + 发送者隔离(推荐用于多账号)。
|
||||
- **`identityLinks`**:将规范 id 映射到带提供商前缀的 peer,用于跨渠道共享会话。
|
||||
- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在 `idleMinutes` 后重置。当两者都配置时,以先到期者为准。每日重置的新鲜度使用会话行的 `sessionStartedAt`;空闲重置的新鲜度使用 `lastInteractionAt`。心跳、cron 唤醒、exec 通知和 Gateway 网关记账等后台 / 系统事件写入可以更新 `updatedAt`,但不会保持每日 / 空闲会话处于新鲜状态。
|
||||
- **`resetByType`**:按类型覆盖(`direct`、`group`、`thread`)。旧版 `dm` 仍可作为 `direct` 的别名使用。
|
||||
- **`parentForkMaxTokens`**:创建分叉线程会话时,父会话允许的最大 `totalTokens`(默认 `100000`)。
|
||||
- 如果父会话的 `totalTokens` 高于此值,OpenClaw 会启动一个新的线程会话,而不是继承父 transcript 历史。
|
||||
- 设为 `0` 可禁用此保护,并始终允许父会话分叉。
|
||||
- **`identityLinks`**:将标准 id 映射到带提供商前缀的 peer,用于跨渠道共享会话。
|
||||
- **`reset`**:主重置策略。`daily` 会在本地时间 `atHour` 重置;`idle` 会在空闲 `idleMinutes` 后重置。当两者都配置时,以先到期者为准。每日重置的新鲜度基于会话行的 `sessionStartedAt`;空闲重置的新鲜度基于 `lastInteractionAt`。诸如 heartbeat、cron 唤醒、exec 通知和 Gateway 网关簿记等后台 / 系统事件写入可能会更新 `updatedAt`,但它们不会让 daily / idle 会话保持新鲜。
|
||||
- **`resetByType`**:按类型覆盖(`direct`、`group`、`thread`)。旧版 `dm` 可作为 `direct` 的别名。
|
||||
- **`parentForkMaxTokens`**:创建分叉线程会话时,允许的父会话最大 `totalTokens`(默认 `100000`)。
|
||||
- 如果父会话的 `totalTokens` 高于此值,OpenClaw 会启动一个全新的线程会话,而不是继承父转录历史。
|
||||
- 设为 `0` 可禁用此保护,并始终允许从父会话分叉。
|
||||
- **`mainKey`**:旧版字段。运行时始终对主直接聊天桶使用 `"main"`。
|
||||
- **`agentToAgent.maxPingPongTurns`**:智能体之间在智能体到智能体交换期间允许的最大来回回复轮次(整数,范围:`0`–`5`)。`0` 会禁用这种乒乓式链路。
|
||||
- **`sendPolicy`**:按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 作为别名)、`keyPrefix` 或 `rawKeyPrefix` 进行匹配。第一个 deny 规则优先。
|
||||
- **`agentToAgent.maxPingPongTurns`**:智能体之间交互时,允许的最大往返回复轮数(整数,范围:`0`–`5`)。`0` 表示禁用乒乓链式交互。
|
||||
- **`sendPolicy`**:可按 `channel`、`chatType`(`direct|group|channel`,旧版 `dm` 为别名)、`keyPrefix` 或 `rawKeyPrefix` 匹配。第一个 deny 优先。
|
||||
- **`maintenance`**:会话存储清理 + 保留控制。
|
||||
- `mode`:`warn` 仅发出警告;`enforce` 会执行清理。
|
||||
- `pruneAfter`:陈旧条目的年龄截止时间(默认 `30d`)。
|
||||
- `pruneAfter`:陈旧条目的年龄阈值(默认 `30d`)。
|
||||
- `maxEntries`:`sessions.json` 中的最大条目数(默认 `500`)。
|
||||
- `rotateBytes`:当 `sessions.json` 超过该大小时进行轮转(默认 `10mb`)。
|
||||
- `resetArchiveRetention`:`*.reset.<timestamp>` transcript 归档的保留时长。默认与 `pruneAfter` 相同;设为 `false` 可禁用。
|
||||
- `maxDiskBytes`:可选的 sessions 目录磁盘预算。在 `warn` 模式下会记录警告;在 `enforce` 模式下会优先删除最旧的工件 / 会话。
|
||||
- `resetArchiveRetention`:`*.reset.<timestamp>` 转录归档的保留时长。默认值与 `pruneAfter` 相同;设为 `false` 可禁用。
|
||||
- `maxDiskBytes`:可选的会话目录磁盘预算。在 `warn` 模式下会记录警告;在 `enforce` 模式下会优先移除最旧的产物 / 会话。
|
||||
- `highWaterBytes`:预算清理后的可选目标值。默认是 `maxDiskBytes` 的 `80%`。
|
||||
- **`threadBindings`**:线程绑定会话功能的全局默认值。
|
||||
- `enabled`:主默认开关(提供商可以覆盖;Discord 使用 `channels.discord.threadBindings.enabled`)
|
||||
- `idleHours`:默认按小时计算的不活跃自动取消聚焦时长(`0` 表示禁用;提供商可以覆盖)
|
||||
- `maxAgeHours`:默认按小时计算的硬性最大时长(`0` 表示禁用;提供商可以覆盖)
|
||||
- `enabled`:主默认开关(提供商可覆盖;Discord 使用 `channels.discord.threadBindings.enabled`)
|
||||
- `idleHours`:默认按小时计算的不活动自动失焦(`0` 表示禁用;提供商可覆盖)
|
||||
- `maxAgeHours`:默认按小时计算的硬性最大时长(`0` 表示禁用;提供商可覆盖)
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -1225,7 +1221,7 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
### 回复前缀
|
||||
|
||||
按渠道 / 账号覆盖:`channels.<channel>.responsePrefix`、`channels.<channel>.accounts.<id>.responsePrefix`。
|
||||
按渠道 / 账号覆盖项:`channels.<channel>.responsePrefix`、`channels.<channel>.accounts.<id>.responsePrefix`。
|
||||
|
||||
解析顺序(越具体越优先):账号 → 渠道 → 全局。`""` 会禁用并停止级联。`"auto"` 会派生为 `[{identity.name}]`。
|
||||
|
||||
@ -1233,10 +1229,10 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
|
||||
| 变量 | 说明 | 示例 |
|
||||
| ----------------- | -------------- | --------------------------- |
|
||||
| `{model}` | 简短模型名 | `claude-opus-4-6` |
|
||||
| `{model}` | 短模型名 | `claude-opus-4-6` |
|
||||
| `{modelFull}` | 完整模型标识符 | `anthropic/claude-opus-4-6` |
|
||||
| `{provider}` | 提供商名称 | `anthropic` |
|
||||
| `{thinkingLevel}` | 当前 thinking 级别 | `high`、`low`、`off` |
|
||||
| `{thinkingLevel}` | 当前思考级别 | `high`、`low`、`off` |
|
||||
| `{identity.name}` | 智能体身份名称 | (与 `"auto"` 相同) |
|
||||
|
||||
变量不区分大小写。`{think}` 是 `{thinkingLevel}` 的别名。
|
||||
@ -1244,17 +1240,17 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
### 确认反应
|
||||
|
||||
- 默认使用当前智能体的 `identity.emoji`,否则为 `"👀"`。设为 `""` 可禁用。
|
||||
- 按渠道覆盖:`channels.<channel>.ackReaction`、`channels.<channel>.accounts.<id>.ackReaction`。
|
||||
- 解析顺序:账号 → 渠道 → `messages.ackReaction` → 身份回退。
|
||||
- 作用域:`group-mentions`(默认)、`group-all`、`direct`、`all`。
|
||||
- 按渠道覆盖项:`channels.<channel>.ackReaction`、`channels.<channel>.accounts.<id>.ackReaction`。
|
||||
- 解析顺序:账号 → 渠道 → `messages.ackReaction` → 身份回退值。
|
||||
- 范围:`group-mentions`(默认)、`group-all`、`direct`、`all`。
|
||||
- `removeAckAfterReply`:在 Slack、Discord 和 Telegram 上,回复后移除确认反应。
|
||||
- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期状态反应。
|
||||
在 Slack 和 Discord 上,未设置时,如果确认反应处于活动状态,则状态反应保持启用。
|
||||
在 Telegram 上,需要显式将其设为 `true` 才会启用生命周期状态反应。
|
||||
- `messages.statusReactions.enabled`:在 Slack、Discord 和 Telegram 上启用生命周期 Status 反应。
|
||||
在 Slack 和 Discord 上,如果未设置,则在确认反应激活时保持 Status 反应启用。
|
||||
在 Telegram 上,需要显式设为 `true` 才会启用生命周期 Status 反应。
|
||||
|
||||
### 入站去抖动
|
||||
### 入站防抖
|
||||
|
||||
将同一发送者的快速连续纯文本消息批处理为一个智能体轮次。媒体 / 附件会立即刷新。控制命令会绕过去抖动。
|
||||
将同一发送者快速连续发送的纯文本消息批量合并为一次智能体轮次。媒体 / 附件会立即刷新。控制命令会绕过防抖。
|
||||
|
||||
### TTS(文本转语音)
|
||||
|
||||
@ -1304,19 +1300,19 @@ scripts/sandbox-browser-setup.sh # 可选浏览器镜像
|
||||
}
|
||||
```
|
||||
|
||||
- `auto` 控制默认自动 TTS 模式:`off`、`always`、`inbound` 或 `tagged`。`/tts on|off` 可以覆盖本地偏好,`/tts status` 会显示实际状态。
|
||||
- `summaryModel` 会覆盖自动摘要所使用的 `agents.defaults.model.primary`。
|
||||
- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认为 `false`(需主动启用)。
|
||||
- API 密钥会回退到 `ELEVENLABS_API_KEY` / `XI_API_KEY` 和 `OPENAI_API_KEY`。
|
||||
- 内置语音提供商由插件所有。如果设置了 `plugins.allow`,请包含你想使用的每个 TTS 提供商插件,例如用于 Edge TTS 的 `microsoft`。旧版提供商 id `edge` 仍可作为 `microsoft` 的别名使用。
|
||||
- `providers.openai.baseUrl` 会覆盖 OpenAI TTS 端点。解析顺序为:配置,然后 `OPENAI_TTS_BASE_URL`,最后是 `https://api.openai.com/v1`。
|
||||
- 当 `providers.openai.baseUrl` 指向非 OpenAI 端点时,OpenClaw 会将其视为 OpenAI 兼容的 TTS 服务器,并放宽模型 / 语音校验。
|
||||
- `auto` 控制默认自动 TTS 模式:`off`、`always`、`inbound` 或 `tagged`。`/tts on|off` 可覆盖本地偏好,`/tts status` 会显示生效状态。
|
||||
- `summaryModel` 会覆盖用于自动摘要的 `agents.defaults.model.primary`。
|
||||
- `modelOverrides` 默认启用;`modelOverrides.allowProvider` 默认为 `false`(需显式启用)。
|
||||
- API key 会回退到 `ELEVENLABS_API_KEY` / `XI_API_KEY` 和 `OPENAI_API_KEY`。
|
||||
- 内置语音提供商由插件负责。如果设置了 `plugins.allow`,请包含你想使用的每个 TTS 提供商插件,例如用于 Edge TTS 的 `microsoft`。旧版提供商 id `edge` 可作为 `microsoft` 的别名。
|
||||
- `providers.openai.baseUrl` 会覆盖 OpenAI TTS 端点。解析顺序为:配置、`OPENAI_TTS_BASE_URL`、然后 `https://api.openai.com/v1`。
|
||||
- 当 `providers.openai.baseUrl` 指向非 OpenAI 端点时,OpenClaw 会将其视为兼容 OpenAI 的 TTS 服务器,并放宽对模型 / 语音的校验。
|
||||
|
||||
---
|
||||
|
||||
## 对话
|
||||
## 通话
|
||||
|
||||
Talk 模式(macOS / iOS / Android)的默认值。
|
||||
Talk 模式(macOS / iOS / Android)的默认设置。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1345,21 +1341,21 @@ Talk 模式(macOS / iOS / Android)的默认值。
|
||||
}
|
||||
```
|
||||
|
||||
- 配置了多个 Talk 提供商时,`talk.provider` 必须与 `talk.providers` 中的某个键匹配。
|
||||
- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容,会自动迁移到 `talk.providers.<provider>`。
|
||||
- 语音 ID 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。
|
||||
- `talk.provider` 在配置了多个 Talk 提供商时,必须匹配 `talk.providers` 中的某个键。
|
||||
- 旧版扁平 Talk 键(`talk.voiceId`、`talk.voiceAliases`、`talk.modelId`、`talk.outputFormat`、`talk.apiKey`)仅用于兼容性,并会自动迁移到 `talk.providers.<provider>`。
|
||||
- Voice ID 会回退到 `ELEVENLABS_VOICE_ID` 或 `SAG_VOICE_ID`。
|
||||
- `providers.*.apiKey` 接受明文字符串或 SecretRef 对象。
|
||||
- 仅当未配置 Talk API 密钥时,才会应用 `ELEVENLABS_API_KEY` 回退。
|
||||
- `providers.*.voiceAliases` 允许 Talk 指令使用易记名称。
|
||||
- `providers.mlx.modelId` 用于选择 macOS 本地 MLX helper 使用的 Hugging Face 仓库。如果省略,macOS 会使用 `mlx-community/Soprano-80M-bf16`。
|
||||
- macOS MLX 播放会在存在时通过内置的 `openclaw-mlx-tts` helper 运行,否则使用 `PATH` 上的可执行文件;`OPENCLAW_MLX_TTS_BIN` 可在开发时覆盖 helper 路径。
|
||||
- `speechLocale` 用于设置 iOS / macOS Talk 语音识别所使用的 BCP 47 locale id。留空则使用设备默认值。
|
||||
- `silenceTimeoutMs` 用于控制 Talk 模式在用户静音后等待多久再发送 transcript。未设置时会保留平台默认的停顿窗口(`macOS` 和 Android 上为 `700 ms`,iOS 上为 `900 ms`)。
|
||||
- 只有在未配置 Talk API key 时,才会使用 `ELEVENLABS_API_KEY` 回退。
|
||||
- `providers.*.voiceAliases` 允许 Talk 指令使用易读名称。
|
||||
- `providers.mlx.modelId` 选择 macOS 本地 MLX helper 使用的 Hugging Face 仓库。如果省略,macOS 会使用 `mlx-community/Soprano-80M-bf16`。
|
||||
- macOS 的 MLX 播放会通过内置的 `openclaw-mlx-tts` helper 运行;如果不存在,则通过 `PATH` 上的可执行文件运行。开发时可用 `OPENCLAW_MLX_TTS_BIN` 覆盖 helper 路径。
|
||||
- `speechLocale` 设置 iOS / macOS Talk 语音识别所使用的 BCP 47 locale id。留空则使用设备默认值。
|
||||
- `silenceTimeoutMs` 控制 Talk 模式在用户静音后等待多久才发送转录内容。未设置时会保持平台默认的停顿窗口(macOS 和 Android 上为 `700 ms`,iOS 上为 `900 ms`)。
|
||||
|
||||
---
|
||||
|
||||
## 相关
|
||||
## 相关内容
|
||||
|
||||
- [配置参考](/zh-CN/gateway/configuration-reference) — 所有其他配置键
|
||||
- [配置](/zh-CN/gateway/configuration) — 常见任务与快速设置
|
||||
- [配置参考](/zh-CN/gateway/configuration-reference) —— 所有其他配置键
|
||||
- [配置](/zh-CN/gateway/configuration) —— 常见任务与快速设置
|
||||
- [配置示例](/zh-CN/gateway/configuration-examples)
|
||||
|
||||
@ -3,21 +3,21 @@ read_when:
|
||||
- 在本地或 CI 中运行测试
|
||||
- 为模型/提供商缺陷添加回归测试
|
||||
- 调试 Gateway 网关 + 智能体行为
|
||||
summary: 测试工具包:unit/e2e/live 测试套件、Docker 运行器,以及每项测试所涵盖的内容
|
||||
summary: 测试工具包:unit/e2e/live 测试套件、Docker 运行器,以及每项测试覆盖的内容
|
||||
title: 测试
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T01:02:53Z"
|
||||
generated_at: "2026-04-26T03:01:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: be861c3934bb2c4b23a5f060fc07294471ce7df112ca82cb9696bba82a81d1e9
|
||||
source_hash: 03ada15a8113b371529ca62f0816442e724dcf837061db871c90212acc87b690
|
||||
source_path: help/testing.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 有三个 Vitest 测试套件(unit/integration、e2e、live)以及少量 Docker 运行器。本文档是一份“我们的测试方式”指南:
|
||||
OpenClaw 有三个 Vitest 测试套件(unit/integration、e2e、live)以及一小组 Docker 运行器。本文档是一份“我们如何测试”的指南:
|
||||
|
||||
- 每个测试套件覆盖什么内容(以及它刻意**不**覆盖什么)。
|
||||
- 常见工作流应运行哪些命令(本地、推送前、调试)。
|
||||
- 每个测试套件覆盖什么(以及它刻意 _不_ 覆盖什么)。
|
||||
- 常见工作流(本地、推送前、调试)应运行哪些命令。
|
||||
- live 测试如何发现凭证并选择模型/提供商。
|
||||
- 如何为真实世界中的模型/提供商问题添加回归测试。
|
||||
|
||||
@ -25,137 +25,139 @@ OpenClaw 有三个 Vitest 测试套件(unit/integration、e2e、live)以及
|
||||
|
||||
大多数时候:
|
||||
|
||||
- 完整门禁(预期在 push 前运行):`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 lane:`pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline`
|
||||
- 完整门禁(预期在推送前执行):`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`
|
||||
|
||||
当你在调试真实提供商/模型时(需要真实凭证):
|
||||
|
||||
- live 测试套件(模型 + Gateway 网关工具/图像探针):`pnpm test:live`
|
||||
- live 测试套件(模型 + Gateway 网关工具/图像探测):`pnpm test:live`
|
||||
- 安静地只运行一个 live 文件:`pnpm test:live -- src/agents/models.profiles.live.test.ts`
|
||||
- Docker live 模型扫描:`pnpm test:docker:live-models`
|
||||
- 每个被选中的模型现在都会运行一次文本轮次以及一次小型 file-read 风格探针。元数据声明支持 `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` 及其 scheduled/release 调用方中。
|
||||
- 现在每个选中的模型都会运行一次文本轮次加一次小型的类似文件读取的探测。元数据声明支持 `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` 和其 scheduled/release 调用方中。
|
||||
- 原生 Codex 绑定聊天冒烟测试:`pnpm test:docker:live-codex-bind`
|
||||
- 在 Codex app-server 路径上运行一个 Docker live lane,绑定一个合成的 Slack 私信并执行 `/codex bind`,运行 `/codex fast` 和 `/codex permissions`,然后验证普通回复和图像附件都是通过原生插件绑定而不是 ACP 路由的。
|
||||
- Crestodian rescue 命令冒烟测试:`pnpm test:live:crestodian-rescue-channel`
|
||||
- 用于消息渠道 rescue 命令表面的选择性双保险检查。它会执行 `/crestodian status`,排队一个持久模型变更,回复 `/crestodian yes`,并验证审计/配置写入路径。
|
||||
- Crestodian planner Docker 冒烟测试:`pnpm test:docker:crestodian-planner`
|
||||
- 在没有配置的容器中运行 Crestodian,并在 `PATH` 上放置一个假的 Claude CLI,验证模糊 planner 回退会转换为经过审计的类型化配置写入。
|
||||
- 在 Codex app-server 路径上运行 Docker live 通道,将一个合成的 Slack 私信 与 `/codex bind` 绑定,执行 `/codex fast` 和 `/codex permissions`,然后验证普通回复和图像附件都是通过原生插件绑定路由,而不是通过 ACP。
|
||||
- Codex app-server harness 冒烟测试:`pnpm test:docker:live-codex-harness`
|
||||
- 通过插件自有的 Codex app-server harness 运行 Gateway 网关智能体轮次,验证 `/codex status` 和 `/codex models`,并且默认执行图像、cron MCP、子智能体和 Guardian 探测。隔离其他 Codex app-server 故障时,可使用 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=0` 关闭子智能体探测。若要聚焦子智能体检查,请关闭其他探测:`OPENCLAW_LIVE_CODEX_HARNESS_IMAGE_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_MCP_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_GUARDIAN_PROBE=0 OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_PROBE=1 pnpm test:docker:live-codex-harness`。
|
||||
除非设置了 `OPENCLAW_LIVE_CODEX_HARNESS_SUBAGENT_ONLY=0`,否则该命令会在子智能体探测后退出。
|
||||
- Crestodian 救援命令冒烟测试:`pnpm test:live:crestodian-rescue-channel`
|
||||
- 对消息渠道救援命令表面的一个自愿启用的双保险检查。它会执行 `/crestodian status`,排队一个持久化模型变更,回复 `/crestodian yes`,并验证审计/配置写入路径。
|
||||
- Crestodian 规划器 Docker 冒烟测试:`pnpm test:docker:crestodian-planner`
|
||||
- 在一个无配置的容器中运行 Crestodian,并在 `PATH` 上放置一个假的 Claude CLI,验证模糊规划器回退会转换为一条带审计的类型化配置写入。
|
||||
- Crestodian 首次运行 Docker 冒烟测试:`pnpm test:docker:crestodian-first-run`
|
||||
- 从空的 OpenClaw 状态目录启动,将裸 `openclaw` 路由到 Crestodian,应用 setup/model/agent/Discord plugin + SecretRef 写入,验证配置,并检查审计条目。相同的 Ring 0 设置路径也在 QA Lab 中通过 `pnpm openclaw qa suite --scenario crestodian-ring-zero-setup` 覆盖。
|
||||
- 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`。
|
||||
- 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`。
|
||||
|
||||
提示:当你只需要一个失败用例时,优先通过下文描述的 allowlist 环境变量来收窄 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 lane 和由 Convex 管理的 live Telegram lane 作业。`OpenClaw Release Checks` 会在发布批准前运行相同的 lane。
|
||||
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 <count>` 调整 worker 数量,或使用 `--concurrency 1` 运行旧的串行 lane。
|
||||
- 任一场景失败时以非零状态退出。当你想保留产物但不希望退出码失败时,可使用 `--allow-failures`。
|
||||
- 支持提供商模式 `live-frontier`、`mock-openai` 和 `aimock`。`aimock` 会启动一个本地的 AIMock 支持的提供商服务器,用于实验性 fixture 和协议 mock 覆盖,而不会替代具备场景感知能力的 `mock-openai` lane。
|
||||
- 默认会并行运行多个选中场景,并使用隔离的 Gateway 网关 worker。`qa-channel` 默认并发数为 4(受所选场景数量限制)。使用 `--concurrency <count>` 调整 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 测试套件。
|
||||
- 保留与主机上 `qa suite` 相同的场景选择行为。
|
||||
- 在一次性 Multipass Linux VM 中运行相同的 QA 测试套件。
|
||||
- 保持与主机上 `qa suite` 相同的场景选择行为。
|
||||
- 复用与 `qa suite` 相同的提供商/模型选择标志。
|
||||
- live 运行会转发适合 guest 使用的受支持 QA 凭证输入:基于环境变量的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`。
|
||||
- 输出目录必须保持在仓库根目录下,以便 guest 能通过挂载的工作区回写。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入常规 QA 报告、摘要以及 Multipass 日志。
|
||||
- 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-key 新手引导,默认配置 Telegram,验证启用插件时会按需安装运行时依赖,运行 doctor,并针对一个模拟的 OpenAI 端点执行一次本地智能体轮次。
|
||||
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可在 Discord 上运行相同的打包安装 lane。
|
||||
- 从当前检出构建一个 npm tarball,在 Docker 中全局安装,运行非交互式 OpenAI API-key 新手引导,默认配置 Telegram,验证启用插件时会按需安装运行时依赖,运行 doctor,并针对一个模拟的 OpenAI 端点运行一次本地智能体轮次。
|
||||
- 使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 可通过 Discord 运行相同的打包安装通道。
|
||||
- `pnpm test:docker:session-runtime-context`
|
||||
- 运行一个确定性的基于构建应用的 Docker 冒烟测试,用于嵌入式运行时上下文 transcript。它会验证隐藏的 OpenClaw 运行时上下文会作为不可显示的自定义消息持久化,而不是泄漏到可见的用户轮次中;随后注入一个受影响的损坏 session JSONL,并验证 `openclaw doctor --fix` 会将其重写到当前活动分支,同时创建备份。
|
||||
- 运行一个确定性的已构建应用 Docker 冒烟测试,用于嵌入式运行时上下文 transcript。它会验证隐藏的 OpenClaw 运行时上下文作为非显示的自定义消息持久化,而不是泄漏到可见的用户轮次中;随后注入一个受影响的损坏 session JSONL,并验证 `openclaw doctor --fix` 会将其重写到当前分支,同时创建备份。
|
||||
- `pnpm test:docker:npm-telegram-live`
|
||||
- 在 Docker 中安装已发布的 OpenClaw 包,运行已安装包的新手引导,通过已安装的 CLI 配置 Telegram,然后复用 live Telegram QA lane,并将该已安装包作为 SUT Gateway 网关。
|
||||
- 默认使用 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`。
|
||||
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证来源。对于 CI/发布自动化,设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,以及 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色密钥。如果在 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色密钥,Docker 包装器会自动选择 Convex。
|
||||
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 可仅为此 lane 覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。
|
||||
- GitHub Actions 将此 lane 暴露为手动维护者工作流 `NPM Telegram Beta E2E`。它不会在 merge 时运行。该工作流使用 `qa-live-shared` environment 和 Convex CI 凭证租约。
|
||||
- 在 Docker 中安装一个已发布的 OpenClaw 包,运行已安装包的新手引导,通过已安装的 CLI 配置 Telegram,然后复用 live Telegram QA 通道,并将该已安装包作为 SUT Gateway 网关。
|
||||
- 默认为 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta`。
|
||||
- 使用与 `pnpm openclaw qa telegram` 相同的 Telegram 环境变量凭证或 Convex 凭证源。对于 CI/发布自动化,设置 `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex`,并提供 `OPENCLAW_QA_CONVEX_SITE_URL` 和角色密钥。如果在 CI 中存在 `OPENCLAW_QA_CONVEX_SITE_URL` 和 Convex 角色密钥,Docker 包装器会自动选择 Convex。
|
||||
- `OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainer` 可仅为此通道覆盖共享的 `OPENCLAW_QA_CREDENTIAL_ROLE`。
|
||||
- GitHub Actions 将此通道暴露为手动维护者工作流 `NPM Telegram Beta E2E`。它不会在合并时运行。该工作流使用 `qa-live-shared` 环境和 Convex CI 凭证租约。
|
||||
- `pnpm test:docker:bundled-channel-deps`
|
||||
- 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过配置编辑启用内置 channel/plugins。
|
||||
- 验证设置发现过程会让未配置插件的运行时依赖保持未安装状态,首次配置后的 Gateway 网关或 doctor 运行会按需安装每个内置插件的运行时依赖,并且第二次重启不会重新安装已激活的依赖。
|
||||
- 还会安装一个已知较旧的 npm 基线版本,在运行 `openclaw update --tag <candidate>` 之前启用 Telegram,并验证候选版本的更新后 doctor 会修复内置渠道运行时依赖,而不需要 harness 侧的 postinstall 修复。
|
||||
- 在 Docker 中打包并安装当前 OpenClaw 构建,启动已配置 OpenAI 的 Gateway 网关,然后通过编辑配置启用内置渠道/plugins。
|
||||
- 验证 setup 发现阶段不会提前安装未配置 plugin 的运行时依赖,首次配置后的 Gateway 网关或 doctor 运行会按需安装每个内置 plugin 的运行时依赖,而第二次重启不会重新安装已经激活的依赖。
|
||||
- 还会安装一个已知的较旧 npm 基线版本,在运行 `openclaw update --tag <candidate>` 之前启用 Telegram,并验证候选版本的更新后 doctor 能修复内置渠道运行时依赖,而不需要 harness 侧的 postinstall 修复。
|
||||
- `pnpm test:parallels:npm-update`
|
||||
- 在 Parallels guest 上运行原生打包安装更新冒烟测试。每个选定的平台都会先安装请求的基线包,然后在同一 guest 中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新状态、gateway 就绪情况以及一次本地智能体轮次。
|
||||
- 在迭代单个 guest 时,使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要产物路径和各 lane 状态。
|
||||
- 用主机超时包装较长的本地运行,避免 Parallels 传输卡住耗尽剩余测试窗口:
|
||||
- 在 Parallels 来宾中运行原生打包安装更新冒烟测试。每个选中的平台都会先安装请求的基线包,然后在同一个来宾中运行已安装的 `openclaw update` 命令,并验证已安装版本、更新状态、gateway 就绪情况以及一次本地智能体轮次。
|
||||
- 在迭代单个来宾时,使用 `--platform macos`、`--platform windows` 或 `--platform linux`。使用 `--json` 获取摘要制品路径和每个通道的状态。
|
||||
- 为较长的本地运行加上主机超时,以避免 Parallels 传输卡顿耗尽剩余测试窗口:
|
||||
|
||||
```bash
|
||||
timeout --foreground 150m pnpm test:parallels:npm-update -- --json
|
||||
timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json
|
||||
```
|
||||
|
||||
- 脚本会将嵌套 lane 日志写入 `/tmp/openclaw-parallels-npm-update.*`。在断定外层包装器卡住之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。
|
||||
- 在冷 guest 上,Windows 更新可能会花费 10 到 15 分钟进行更新后 doctor/运行时依赖修复;只要嵌套的 npm 调试日志仍在推进,这仍属于健康状态。
|
||||
- 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟 lane 并行运行。它们共享 VM 状态,可能在快照恢复、包服务或 guest gateway 状态上发生冲突。
|
||||
- 更新后的证明会运行常规内置插件表面,因为即使智能体轮次本身只检查简单的文本响应,语音、图像生成和媒体理解等能力门面仍然是通过内置运行时 API 加载的。
|
||||
- 该脚本会将嵌套通道日志写入 `/tmp/openclaw-parallels-npm-update.*`。在假定外层包装器卡住之前,先检查 `windows-update.log`、`macos-update.log` 或 `linux-update.log`。
|
||||
- Windows 更新在冷启动来宾上可能会花费 10 到 15 分钟进行更新后 doctor/运行时依赖修复;只要嵌套的 npm 调试日志仍在推进,这仍然是健康状态。
|
||||
- 不要将这个聚合包装器与单独的 Parallels macOS、Windows 或 Linux 冒烟通道并行运行。它们共享 VM 状态,可能在快照恢复、包服务或来宾 gateway 状态上发生冲突。
|
||||
- 更新后的验证会运行常规的内置 plugin 表面,因为像语音、图像生成和媒体理解这样的能力门面会通过内置运行时 API 加载,即使智能体轮次本身只检查一个简单的文本响应。
|
||||
|
||||
- `pnpm openclaw qa aimock`
|
||||
- 仅启动本地 AIMock 提供商服务器,用于直接协议冒烟测试。
|
||||
- 仅启动本地 AIMock 提供商服务器,用于直接的协议冒烟测试。
|
||||
- `pnpm openclaw qa matrix`
|
||||
- 针对一次性的基于 Docker 的 Tuwunel homeserver 运行 Matrix live QA lane。
|
||||
- 这个 QA 主机目前仅供仓库/开发使用。打包后的 OpenClaw 安装不会附带 `qa-lab`,因此也不会暴露 `openclaw qa`。
|
||||
- 针对一次性的 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 不暴露共享凭证来源标志,因为该 lane 会在本地预配一次性用户。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入 Matrix QA 报告、摘要、observed-events 产物以及合并后的 stdout/stderr 输出日志。
|
||||
- 默认输出进度,并通过 `OPENCLAW_QA_MATRIX_TIMEOUT_MS` 强制执行硬性运行超时(默认 30 分钟)。清理由 `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS` 限制,失败信息中会包含恢复命令 `docker compose ... down --remove-orphans`。
|
||||
- 预配三个临时 Matrix 用户(`driver`、`sut`、`observer`)以及一个私有房间,然后以真实 Matrix plugin 作为 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/...`。
|
||||
- 默认会输出进度,并通过 `OPENCLAW_QA_MATRIX_TIMEOUT_MS`(默认 30 分钟)强制执行硬性运行超时。清理由 `OPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS` 限定;失败信息中会包含用于恢复的 `docker compose ... down --remove-orphans` 命令。
|
||||
- `pnpm openclaw qa telegram`
|
||||
- 使用环境变量中的 driver 和 SUT bot token,针对真实私有群组运行 Telegram live QA lane。
|
||||
- 需要 `OPENCLAW_QA_TELEGRAM_GROUP_ID`、`OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` 和 `OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN`。group id 必须是 Telegram chat 的数字 id。
|
||||
- 支持 `--credential-source convex` 以使用共享凭证池。默认使用 env 模式,或者设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用池化租约。
|
||||
- 任一场景失败时以非零状态退出。当你想保留产物但不希望退出码失败时,可使用 `--allow-failures`。
|
||||
- 需要同一个私有群组中的两个不同 bot,且 SUT bot 必须暴露 Telegram 用户名。
|
||||
- 为了实现稳定的 bot 对 bot 观察,请在 `@BotFather` 中为两个 bot 启用 Bot-to-Bot Communication Mode,并确保 driver bot 能观察群组中的 bot 流量。
|
||||
- 在 `.artifacts/qa-e2e/...` 下写入 Telegram QA 报告、摘要以及 observed-messages 产物。回复场景包含从 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` 以使用共享凭证池。默认使用环境变量模式,或者设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex` 以启用共享租约。
|
||||
- 任一场景失败时都会以非零状态退出。若你想保留制品但不使用失败退出码,可使用 `--allow-failures`。
|
||||
- 需要同一私有群组中的两个不同 bot,且 SUT bot 需要暴露 Telegram 用户名。
|
||||
- 为了稳定地观察 bot 之间的通信,请在 `@BotFather` 中为两个 bot 都启用 Bot-to-Bot Communication Mode,并确保 driver bot 能观察群组中的 bot 流量。
|
||||
- 会将 Telegram QA 报告、摘要和 observed-messages 制品写入 `.artifacts/qa-e2e/...`。回复类场景还会包含从 driver 发送请求到观察到 SUT 回复的 RTT。
|
||||
|
||||
live 传输 lane 共享一个标准契约,以避免新传输发生漂移:
|
||||
live 传输通道共享一个标准契约,以避免新传输发生漂移:
|
||||
|
||||
`qa-channel` 仍然是广覆盖的合成 QA 测试套件,不属于 live 传输覆盖矩阵的一部分。
|
||||
`qa-channel` 仍然是广义的合成 QA 测试套件,不属于 live 传输覆盖矩阵的一部分。
|
||||
|
||||
| Lane | Canary | Mention gating | Allowlist block | Top-level reply | Restart resume | Thread follow-up | Thread isolation | Reaction observation | Help command |
|
||||
| -------- | ------ | -------------- | --------------- | --------------- | -------------- | ---------------- | ---------------- | -------------------- | ------------ |
|
||||
| Matrix | x | x | x | x | x | x | x | x | |
|
||||
| Telegram | x | | | | | | | | x |
|
||||
| 通道 | Canary | Mention gating | Allowlist block | 顶层回复 | 重启恢复 | 线程后续回复 | 线程隔离 | Reaction 观察 | 帮助命令 |
|
||||
| ---- | ------ | -------------- | --------------- | -------- | -------- | ------------ | -------- | -------------- | -------- |
|
||||
| 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 支持的池中获取一个独占租约,在 lane 运行期间为该租约发送心跳,并在关闭时释放租约。
|
||||
当为 `openclaw qa telegram` 启用 `--credential-source convex`(或 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`)时,QA lab 会从 Convex 支持的池中获取独占租约,在通道运行期间维持该租约心跳,并在关闭时释放租约。
|
||||
|
||||
参考 Convex 项目脚手架:
|
||||
|
||||
- `qa/convex-credential-broker/`
|
||||
|
||||
必需的环境变量:
|
||||
所需环境变量:
|
||||
|
||||
- `OPENCLAW_QA_CONVEX_SITE_URL`(例如 `https://your-deployment.convex.site`)
|
||||
- 为所选角色提供一个密钥:
|
||||
- `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`)
|
||||
|
||||
可选环境变量:
|
||||
|
||||
@ -164,14 +166,14 @@ live 传输 lane 共享一个标准契约,以避免新传输发生漂移:
|
||||
- `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_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 辅助命令:
|
||||
为维护者提供的 CLI 辅助命令:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa credentials doctor
|
||||
@ -180,14 +182,14 @@ pnpm openclaw qa credentials list --kind telegram
|
||||
pnpm openclaw qa credentials remove --credential-id <credential-id>
|
||||
```
|
||||
|
||||
在 live 运行之前使用 `doctor`,可检查 Convex site URL、broker 密钥、端点前缀、HTTP 超时以及管理/列出可达性,同时不打印密钥值。在脚本和 CI 工具中可使用 `--json` 获取机器可读输出。
|
||||
在 live 运行前使用 `doctor`,以检查 Convex site URL、broker 密钥、endpoint 前缀、HTTP 超时以及 admin/list 可达性,同时不会打印密钥值。在脚本和 CI 工具中使用 `--json` 获取机器可读输出。
|
||||
|
||||
默认端点契约(`OPENCLAW_QA_CONVEX_SITE_URL` + `/qa-credentials/v1`):
|
||||
默认 endpoint 契约(`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`)
|
||||
@ -205,62 +207,62 @@ pnpm openclaw qa credentials remove --credential-id <credential-id>
|
||||
- 请求:`{ kind?, status?, includePayload?, limit? }`
|
||||
- 成功:`{ status: "ok", credentials, count }`
|
||||
|
||||
Telegram kind 的 payload 结构:
|
||||
Telegram 类型的负载结构:
|
||||
|
||||
- `{ groupId: string, driverToken: string, sutToken: string }`
|
||||
- `groupId` 必须是 Telegram chat id 的数字字符串。
|
||||
- 对于 `kind: "telegram"`,`admin/add` 会验证此结构,并拒绝格式错误的 payload。
|
||||
- `groupId` 必须是数字形式的 Telegram chat id 字符串。
|
||||
- `admin/add` 会在 `kind: "telegram"` 时验证此结构,并拒绝格式错误的负载。
|
||||
|
||||
### 向 QA 添加一个渠道
|
||||
|
||||
向 Markdown QA 系统添加一个渠道,严格来说只需要两样东西:
|
||||
将一个渠道添加到 Markdown QA 系统中,恰好需要两样东西:
|
||||
|
||||
1. 一个适用于该渠道的传输适配器。
|
||||
2. 一个用于执行渠道契约的场景包。
|
||||
1. 该渠道的传输适配器。
|
||||
2. 一个用于验证渠道契约的场景包。
|
||||
|
||||
如果共享的 `qa-lab` 主机可以拥有该流程,就不要新增顶层 QA 命令根。
|
||||
当共享的 `qa-lab` 主机能够负责整个流程时,不要添加新的顶层 QA 命令根。
|
||||
|
||||
`qa-lab` 负责共享主机机制:
|
||||
|
||||
- `openclaw qa` 命令根
|
||||
- 测试套件启动和拆除
|
||||
- worker 并发
|
||||
- 产物写入
|
||||
- 制品写入
|
||||
- 报告生成
|
||||
- 场景执行
|
||||
- 旧版 `qa-channel` 场景的兼容别名
|
||||
- 对旧 `qa-channel` 场景的兼容别名
|
||||
|
||||
运行器插件负责传输契约:
|
||||
|
||||
- `openclaw qa <runner>` 如何挂载在共享的 `qa` 根下
|
||||
- `openclaw qa <runner>` 如何挂载到共享的 `qa` 根命令下
|
||||
- 如何为该传输配置 gateway
|
||||
- 如何检查就绪状态
|
||||
- 如何注入入站事件
|
||||
- 如何观察出站消息
|
||||
- 如何暴露 transcript 和规范化后的传输状态
|
||||
- 如何执行由传输支持的操作
|
||||
- 如何处理传输特定的重置或清理
|
||||
- 如何暴露 transcript 和标准化后的传输状态
|
||||
- 如何执行基于传输的操作
|
||||
- 如何处理传输专属的重置或清理
|
||||
|
||||
新渠道的最低接入门槛是:
|
||||
新渠道的最低采纳标准是:
|
||||
|
||||
1. 保持 `qa-lab` 作为共享 `qa` 根的所有者。
|
||||
1. 保持 `qa-lab` 作为共享 `qa` 根命令的所有者。
|
||||
2. 在共享的 `qa-lab` 主机接缝上实现传输运行器。
|
||||
3. 将传输特定机制保留在运行器插件或渠道 harness 内部。
|
||||
4. 将运行器挂载为 `openclaw qa <runner>`,而不是注册一个竞争性的根命令。
|
||||
3. 将传输专属机制保留在运行器插件或渠道 harness 内部。
|
||||
4. 将运行器挂载为 `openclaw qa <runner>`,而不是注册一个竞争的根命令。
|
||||
运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。
|
||||
保持 `runtime-api.ts` 轻量;惰性 CLI 和运行器执行应保留在独立入口点之后。
|
||||
5. 在主题化的 `qa/scenarios/` 目录下编写或改造 Markdown 场景。
|
||||
6. 为新场景使用通用场景辅助方法。
|
||||
7. 保持现有兼容别名继续可用,除非仓库正在进行有意的迁移。
|
||||
保持 `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`
|
||||
@ -275,7 +277,7 @@ Telegram kind 的 payload 结构:
|
||||
- `formatTransportTranscript`
|
||||
- `resetTransport`
|
||||
|
||||
现有场景仍可使用兼容别名,包括:
|
||||
现有场景仍可使用以下兼容别名:
|
||||
|
||||
- `waitForQaChannelReady`
|
||||
- `waitForOutboundMessage`
|
||||
@ -283,21 +285,21 @@ Telegram kind 的 payload 结构:
|
||||
- `formatConversationTranscript`
|
||||
- `resetBus`
|
||||
|
||||
新的渠道工作应使用这些通用辅助方法名称。
|
||||
兼容别名的存在是为了避免一次性迁移日,而不是作为新场景编写的范式。
|
||||
新的渠道工作应使用通用辅助函数名称。
|
||||
兼容别名的存在是为了避免一次性迁移,不应作为新场景编写的范式。
|
||||
|
||||
## 测试套件(哪些内容在哪里运行)
|
||||
## 测试套件(各自运行位置)
|
||||
|
||||
可以把这些测试套件理解为“真实性逐步增加”(同时波动性/成本也逐步增加):
|
||||
可以把这些测试套件理解为“真实度逐步提升”(同时不稳定性/成本也逐步增加):
|
||||
|
||||
### Unit / integration(默认)
|
||||
|
||||
- 命令:`pnpm test`
|
||||
- 配置:未定向运行使用 `vitest.full-*.config.ts` 分片集合,并且可能会将多项目分片展开为按项目划分的配置,以便并行调度
|
||||
- 文件:核心/unit 清单位于 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts`,以及 `vitest.unit.config.ts` 覆盖的白名单 `ui` node 测试中
|
||||
- 配置:未定向运行使用 `vitest.full-*.config.ts` 分片集,并且可能将多项目分片展开为逐项目配置,以便并行调度
|
||||
- 文件:核心/unit 清单位于 `src/**/*.test.ts`、`packages/**/*.test.ts`、`test/**/*.test.ts`,以及由 `vitest.unit.config.ts` 覆盖的白名单 `ui` node 测试
|
||||
- 范围:
|
||||
- 纯 unit 测试
|
||||
- 进程内 integration 测试(gateway 鉴权、路由、工具、解析、配置)
|
||||
- 纯单元测试
|
||||
- 进程内集成测试(gateway 认证、路由、工具、解析、配置)
|
||||
- 针对已知缺陷的确定性回归测试
|
||||
- 预期:
|
||||
- 在 CI 中运行
|
||||
@ -305,65 +307,65 @@ Telegram kind 的 payload 结构:
|
||||
- 应当快速且稳定
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="项目、分片和作用域 lane">
|
||||
<Accordion title="项目、分片和定向通道">
|
||||
|
||||
- 未定向的 `pnpm test` 会运行 12 个较小的分片配置(`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` 会先通过带作用域的 lane 路由显式文件/目录目标,因此 `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` 可以避免承担完整根项目启动的成本。
|
||||
- 当 diff 仅涉及可路由的源码/测试文件时,`pnpm test:changed` 会将变更过的 git 路径展开到相同的带作用域 lane;配置/setup 编辑仍会回退到更广泛的根项目重跑。
|
||||
- `pnpm check:changed` 是针对小范围工作使用的常规智能本地门禁。它会将 diff 分类为 core、core tests、extensions、extension tests、apps、docs、release metadata、live Docker tooling 和 tooling,然后运行匹配的 typecheck/lint/test lane。公开的 Plugin SDK 和插件契约变更会额外包含一次 extension 验证,因为 extensions 依赖这些 core 契约。仅涉及发布元数据的版本号变更会运行有针对性的版本/配置/根依赖检查,而不是完整测试套件,并带有一个保护机制,用于拒绝顶层版本字段之外的 package 更改。
|
||||
- live Docker ACP harness 编辑会运行一个聚焦的本地门禁:live Docker 鉴权脚本的 shell 语法检查、live Docker 调度器 dry-run、ACP bind unit 测试以及 ACPX extension 测试。仅当 diff 限定在 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、导出、版本和其他 package 表面编辑仍然使用更广泛的保护。
|
||||
- 来自 agents、commands、plugins、auto-reply 辅助方法、`plugin-sdk` 以及类似纯工具区域的轻导入 unit 测试会通过 `unit-fast` lane 路由,该 lane 会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有 lane 上。
|
||||
- 部分 `plugin-sdk` 和 `commands` 辅助源码文件还会在 changed 模式下将运行映射到这些轻量 lane 中显式的同级测试,因此辅助方法编辑可以避免为该目录重跑完整的重型测试套件。
|
||||
- `auto-reply` 为顶层 core 辅助方法、顶层 `reply.*` integration 测试以及 `src/auto-reply/reply/**` 子树提供了专用分桶。CI 还会进一步将 reply 子树拆分为 agent-runner、dispatch 和 commands/state-routing 分片,这样某一个重导入分桶就不会独占整个 Node 收尾阶段。
|
||||
- 未定向的 `pnpm test` 会运行 12 个更小的分片配置(`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` 项目图,因为多分片观察循环并不现实。
|
||||
- `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` 是针对小范围工作的常规智能本地门禁。它会将差异分类为 core、core tests、extensions、extension tests、apps、docs、发布元数据、live Docker 工具和工具链,然后运行匹配的 typecheck/lint/test 通道。公开的 Plugin SDK 和插件契约变更会额外包含一次 extension 验证,因为 extensions 依赖这些 core 契约。仅包含发布元数据的版本号提升会运行定向的版本/配置/根依赖检查,而不是完整测试套件,并带有一个保护机制,用于拒绝顶层版本字段之外的包变更。
|
||||
- live Docker ACP harness 修改会运行一个聚焦的本地门禁:对 live Docker 认证脚本进行 shell 语法检查、执行 live Docker 调度器 dry-run、运行 ACP bind unit 测试以及 ACPX extension 测试。只有当差异被限制在 `scripts["test:docker:live-*"]` 时,才会包含 `package.json` 变更;依赖、导出、版本和其他包表面修改仍会使用更广泛的保护。
|
||||
- 来自智能体、commands、plugins、auto-reply 辅助函数、`plugin-sdk` 以及类似纯工具区域的轻导入 unit 测试会路由到 `unit-fast` 通道,该通道会跳过 `test/setup-openclaw-runtime.ts`;有状态/运行时较重的文件仍保留在现有通道上。
|
||||
- 某些选定的 `plugin-sdk` 和 `commands` 辅助源文件,也会在 changed 模式运行中将变更映射到这些轻量通道中的显式同级测试,因此辅助函数修改无需为该目录重跑完整的重型测试套件。
|
||||
- `auto-reply` 为顶层 core 辅助函数、顶层 `reply.*` 集成测试以及 `src/auto-reply/reply/**` 子树提供了专用分桶。CI 还会进一步将 reply 子树拆分为智能体运行器、分发以及命令/状态路由分片,以避免某个导入开销高的分桶独占整个 Node 收尾阶段。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="嵌入式运行器覆盖范围">
|
||||
<Accordion title="内嵌运行器覆盖">
|
||||
|
||||
- 当你修改消息工具发现输入或压缩运行时上下文时,请同时保持两个层级的覆盖。
|
||||
- 为纯路由和规范化边界添加聚焦的辅助回归测试。
|
||||
- 保持嵌入式运行器 integration 测试套件健康:
|
||||
- 当你修改消息工具发现输入或压缩运行时上下文时,请同时保持这两个层级的覆盖。
|
||||
- 为纯路由和标准化边界添加聚焦的辅助函数回归测试。
|
||||
- 保持内嵌运行器集成测试套件健康:
|
||||
`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` 路径;仅辅助方法级测试并不能充分替代这些 integration 路径。
|
||||
- 这些测试套件会验证作用域 id 和压缩行为仍然通过真实的 `run.ts` / `compact.ts` 路径流动;仅有辅助函数测试并不能充分替代这些集成路径。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Vitest 池和隔离默认值">
|
||||
|
||||
- 基础 Vitest 配置默认使用 `threads`。
|
||||
- 共享 Vitest 配置固定为 `isolate: false`,并在根项目、e2e 和 live 配置中使用非隔离运行器。
|
||||
- 根 UI lane 保留其 `jsdom` setup 和优化器,但也运行在共享的非隔离运行器上。
|
||||
- 每个 `pnpm test` 分片都从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。
|
||||
- `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与 stock V8 行为进行对比。
|
||||
- 共享 Vitest 配置固定 `isolate: false`,并在根项目、e2e 和 live 配置中使用非隔离运行器。
|
||||
- 根 UI 通道保留其 `jsdom` 设置和优化器,但也运行在共享的非隔离运行器上。
|
||||
- 每个 `pnpm test` 分片都会从共享 Vitest 配置继承相同的 `threads` + `isolate: false` 默认值。
|
||||
- `scripts/run-vitest.mjs` 默认会为 Vitest 子 Node 进程添加 `--no-maglev`,以减少大型本地运行期间的 V8 编译抖动。设置 `OPENCLAW_VITEST_ENABLE_MAGLEV=1` 可与标准 V8 行为进行对比。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="快速本地迭代">
|
||||
|
||||
- `pnpm changed:lanes` 会显示一个 diff 会触发哪些架构 lane。
|
||||
- pre-commit hook 仅负责格式化。它会重新暂存已格式化文件,不会运行 lint、typecheck 或测试。
|
||||
- 在交接或 push 前,如果你需要智能本地门禁,请显式运行 `pnpm check:changed`。公开的 Plugin SDK 和插件契约变更会额外包含一次 extension 验证。
|
||||
- 当变更路径能清晰映射到更小的测试套件时,`pnpm test:changed` 会通过带作用域的 lane 路由。
|
||||
- `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 changed:lanes` 会显示某个差异触发了哪些架构通道。
|
||||
- pre-commit hook 只负责格式化。它会重新暂存格式化后的文件,不会运行 lint、typecheck 或测试。
|
||||
- 在交接或推送前,当你需要智能本地门禁时,请显式运行 `pnpm check:changed`。公开的 Plugin SDK 和插件契约变更会额外包含一次 extension 验证。
|
||||
- 当变更路径能够清晰映射到较小测试套件时,`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`。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="性能调试">
|
||||
|
||||
- `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入拆解输出。
|
||||
- `pnpm test:perf:imports:changed` 会将相同的性能分析视图限定到自 `origin/main` 以来变更的文件。
|
||||
- `pnpm test:perf:imports` 会启用 Vitest 导入耗时报告以及导入拆分输出。
|
||||
- `pnpm test:perf:imports:changed` 会将相同的分析视图限定到自 `origin/main` 以来发生变更的文件。
|
||||
- 分片耗时数据会写入 `.artifacts/vitest-shard-timings.json`。
|
||||
整个配置运行以配置路径作为键;带 include-pattern 的 CI 分片会附加分片名称,以便单独跟踪经过过滤的分片。
|
||||
- 当某个热点测试的大部分时间仍花在启动导入上时,应将重依赖放在狭窄的本地 `*.runtime.ts` 接缝之后,并直接 mock 该接缝,而不是为了传给 `vi.mock(...)` 就深度导入运行时辅助方法。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会针对该已提交 diff,将经路由的 `test:changed` 与原生根项目路径进行比较,并输出墙钟时间以及 macOS 最大 RSS。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到 `scripts/test-projects.mjs` 和根 Vitest 配置,对当前脏工作树进行基准测试。
|
||||
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动和转换开销写出主线程 CPU profile。
|
||||
整体配置运行使用配置路径作为键;基于 include-pattern 的 CI 分片会附加分片名称,以便单独跟踪过滤后的分片。
|
||||
- 当某个热点测试仍然把大部分时间花在启动导入上时,应把重依赖放在一个狭窄的本地 `*.runtime.ts` 接缝之后,并直接 mock 该接缝,而不是为了传给 `vi.mock(...)` 就深度导入运行时辅助函数。
|
||||
- `pnpm test:perf:changed:bench -- --ref <git-ref>` 会将定向的 `test:changed` 与该已提交差异的原生根项目路径进行比较,并打印墙钟时间以及 macOS 最大 RSS。
|
||||
- `pnpm test:perf:changed:bench -- --worktree` 会通过将变更文件列表路由到 `scripts/test-projects.mjs` 和根 Vitest 配置,对当前带脏改动的工作树进行基准测试。
|
||||
- `pnpm test:perf:profile:main` 会为 Vitest/Vite 启动与转换开销写出主线程 CPU profile。
|
||||
- `pnpm test:perf:profile:runner` 会在禁用文件并行的情况下,为 unit 测试套件写出运行器 CPU + 堆 profile。
|
||||
|
||||
</Accordion>
|
||||
@ -372,38 +374,38 @@ Telegram kind 的 payload 结构:
|
||||
### 稳定性(gateway)
|
||||
|
||||
- 命令:`pnpm test:stability:gateway`
|
||||
- 配置:`vitest.gateway.config.ts`,强制使用单 worker
|
||||
- 配置:`vitest.gateway.config.ts`,强制单 worker
|
||||
- 范围:
|
||||
- 默认启动一个启用了诊断功能的真实 loopback Gateway 网关
|
||||
- 启动一个真实的 loopback Gateway 网关,并默认启用诊断
|
||||
- 通过诊断事件路径驱动合成的 gateway 消息、内存和大负载抖动
|
||||
- 通过 Gateway 网关 WS RPC 查询 `diagnostics.stability`
|
||||
- 覆盖诊断稳定性 bundle 持久化辅助方法
|
||||
- 断言记录器保持有界、合成 RSS 样本保持在压力预算之下,并且每个 session 的队列深度最终回落为零
|
||||
- 覆盖诊断稳定性 bundle 持久化辅助函数
|
||||
- 断言记录器保持有界、合成 RSS 样本保持在压力预算之下,并且每个会话的队列深度最终回落到零
|
||||
- 预期:
|
||||
- 对 CI 安全且不需要密钥
|
||||
- 是用于稳定性回归跟进的窄范围 lane,不替代完整 Gateway 网关测试套件
|
||||
- 对 CI 安全且无需密钥
|
||||
- 这是一个用于稳定性回归跟进的窄通道,而不是完整 Gateway 网关测试套件的替代品
|
||||
|
||||
### E2E(gateway 冒烟)
|
||||
### E2E(gateway 冒烟测试)
|
||||
|
||||
- 命令:`pnpm test:e2e`
|
||||
- 配置:`vitest.e2e.config.ts`
|
||||
- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及 `extensions/` 下的内置插件 E2E 测试
|
||||
- 文件:`src/**/*.e2e.test.ts`、`test/**/*.e2e.test.ts`,以及位于 `extensions/` 下的内置插件 E2E 测试
|
||||
- 运行时默认值:
|
||||
- 使用 Vitest `threads` 且 `isolate: false`,与仓库其余部分保持一致。
|
||||
- 使用自适应 worker(CI:最多 2 个,本地:默认 1 个)。
|
||||
- 默认以静默模式运行,以减少控制台 I/O 开销。
|
||||
- 有用的覆盖项:
|
||||
- `OPENCLAW_E2E_WORKERS=<n>` 用于强制指定 worker 数量(上限为 16)。
|
||||
- `OPENCLAW_E2E_VERBOSE=1` 用于重新启用详细控制台输出。
|
||||
- `OPENCLAW_E2E_WORKERS=<n>` 可强制指定 worker 数量(上限为 16)。
|
||||
- `OPENCLAW_E2E_VERBOSE=1` 可重新启用详细控制台输出。
|
||||
- 范围:
|
||||
- 多实例 gateway 端到端行为
|
||||
- WebSocket/HTTP 表面、节点配对和更重的网络交互
|
||||
- WebSocket/HTTP 表面、节点配对以及更重的网络交互
|
||||
- 预期:
|
||||
- 在 CI 中运行(当流水线启用时)
|
||||
- 不需要真实密钥
|
||||
- 比 unit 测试有更多运动部件(可能更慢)
|
||||
- 比 unit 测试包含更多活动部件(可能更慢)
|
||||
|
||||
### E2E:OpenShell 后端冒烟
|
||||
### E2E:OpenShell 后端冒烟测试
|
||||
|
||||
- 命令:`pnpm test:e2e:openshell`
|
||||
- 文件:`extensions/openshell/src/backend.e2e.test.ts`
|
||||
@ -411,137 +413,132 @@ Telegram kind 的 payload 结构:
|
||||
- 通过 Docker 在主机上启动一个隔离的 OpenShell gateway
|
||||
- 从临时本地 Dockerfile 创建一个沙箱
|
||||
- 通过真实的 `sandbox ssh-config` + SSH exec 运行 OpenClaw 的 OpenShell 后端
|
||||
- 通过沙箱 fs bridge 验证远端规范文件系统行为
|
||||
- 通过沙箱 fs bridge 验证远程规范文件系统行为
|
||||
- 预期:
|
||||
- 仅按需启用;不属于默认 `pnpm test:e2e` 运行的一部分
|
||||
- 需要本地 `openshell` CLI 以及可用的 Docker daemon
|
||||
- 仅限显式启用;不属于默认的 `pnpm test:e2e` 运行
|
||||
- 需要本地 `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(真实提供商 + 真实模型)
|
||||
### live(真实提供商 + 真实模型)
|
||||
|
||||
- 命令:`pnpm test:live`
|
||||
- 配置:`vitest.live.config.ts`
|
||||
- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及 `extensions/` 下的内置插件 live 测试
|
||||
- 文件:`src/**/*.live.test.ts`、`test/**/*.live.test.ts`,以及位于 `extensions/` 下的内置插件 live 测试
|
||||
- 默认:由 `pnpm test:live` **启用**(设置 `OPENCLAW_LIVE_TEST=1`)
|
||||
- 范围:
|
||||
- “这个提供商/模型**今天**在真实凭证下真的能工作吗?”
|
||||
- 捕获提供商格式变更、工具调用怪癖、鉴权问题以及限流行为
|
||||
- “这个提供商/模型在 _今天_ 配合真实凭证是否真的可用?”
|
||||
- 捕获提供商格式变化、工具调用怪癖、认证问题以及限流行为
|
||||
- 预期:
|
||||
- 天生不适合作为稳定 CI(真实网络、真实提供商策略、配额、故障)
|
||||
- 会花钱 / 消耗限流额度
|
||||
- 优先运行收窄后的子集,而不是“全部”
|
||||
- live 运行会 source `~/.profile`,以便拾取缺失的 API key。
|
||||
- 默认情况下,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 key 轮换(按提供商):设置 `*_API_KEYS`,使用逗号/分号格式,或设置 `*_API_KEY_1`、`*_API_KEY_2`(例如 `OPENAI_API_KEYS`、`ANTHROPIC_API_KEYS`、`GEMINI_API_KEYS`),也可通过 `OPENCLAW_LIVE_*_KEY` 进行每次 live 覆盖;测试会在收到限流响应时重试。
|
||||
- 按设计不具备 CI 稳定性(真实网络、真实提供商策略、配额、故障)
|
||||
- 会花钱 / 使用限流额度
|
||||
- 更适合运行收窄后的子集,而不是“全部”
|
||||
- live 运行会 source `~/.profile` 以获取缺失的 API key。
|
||||
- 默认情况下,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 key 轮换(按提供商):可设置逗号/分号格式的 `*_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/探针心跳。
|
||||
- live 测试套件现在会将进度行输出到 stderr,因此即使 Vitest 控制台捕获处于安静模式,长时间的提供商调用也会显示为活跃状态。
|
||||
- `vitest.live.config.ts` 会禁用 Vitest 控制台拦截,以便提供商/gateway 进度行在 live 运行期间立即流式输出。
|
||||
- 使用 `OPENCLAW_LIVE_HEARTBEAT_MS` 调整直接模型心跳。
|
||||
- 使用 `OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS` 调整 gateway/探测心跳。
|
||||
|
||||
## 我应该运行哪个测试套件?
|
||||
|
||||
使用这个决策表:
|
||||
使用下面这个决策表:
|
||||
|
||||
- 编辑逻辑/测试:运行 `pnpm test`(如果你改动很多,也运行 `pnpm test:coverage`)
|
||||
- 涉及 gateway 网络 / WS 协议 / 配对:额外运行 `pnpm test:e2e`
|
||||
- 调试“我的 bot 挂了”/ 提供商特定故障 / 工具调用:运行收窄后的 `pnpm test:live`
|
||||
- 修改逻辑/测试:运行 `pnpm test`(如果改动很多,再运行 `pnpm test:coverage`)
|
||||
- 触及 gateway 网络 / WS 协议 / 配对:额外运行 `pnpm test:e2e`
|
||||
- 调试“我的 bot 挂了”/ 提供商专属故障 / 工具调用:运行收窄后的 `pnpm test:live`
|
||||
|
||||
## Live(触及网络的)测试
|
||||
## live(接触网络的)测试
|
||||
|
||||
有关 live 模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex app-server harness,以及所有媒体提供商 live 测试(Deepgram、BytePlus(国际版)、ComfyUI、image、music、video、media harness)——以及 live 运行的凭证处理——请参见 [测试 — live 测试套件](/zh-CN/help/testing-live)。
|
||||
有关 live 模型矩阵、CLI 后端冒烟测试、ACP 冒烟测试、Codex app-server harness,以及所有媒体提供商 live 测试(Deepgram、BytePlus(国际版)、ComfyUI、图像、音乐、视频、媒体 harness)——以及 live 运行的凭证处理——请参见[测试——live 测试套件](/zh-CN/help/testing-live)。
|
||||
|
||||
## Docker 运行器(可选的“在 Linux 中可运行”检查)
|
||||
## Docker 运行器(可选的“在 Linux 中可用”检查)
|
||||
|
||||
这些 Docker 运行器分为两类:
|
||||
|
||||
- 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`),并挂载你的本地配置目录和工作区(如果已挂载,也会 source `~/.profile`)。对应的本地入口点是 `test:live:models-profiles` 和 `test:live:gateway-profiles`。
|
||||
- Docker live 运行器默认采用较小的冒烟上限,以便完整的 Docker 扫描仍然可行:
|
||||
- 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`),并挂载你的本地配置目录和工作区(如果已挂载,还会 source `~/.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 lane 中复用它。它还会通过 `test:docker:e2e-build` 构建一个共享的 `scripts/e2e/Dockerfile` 镜像,并在运行已构建应用的 E2E 容器冒烟运行器中复用该镜像。这个聚合流程使用带权重的本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位,而资源上限会防止重型 live、npm-install 和多服务 lane 同时全部启动。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=6`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=8` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有当 Docker 主机有更多余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。该运行器默认执行 Docker 预检,移除陈旧的 OpenClaw E2E 容器,每 30 秒打印一次状态,将成功 lane 的耗时存储到 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中利用这些耗时优先启动更长的 lane。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可在不构建或运行 Docker 的情况下打印带权重的 lane 清单。
|
||||
`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 容器冒烟运行器。该聚合运行器使用加权本地调度器:`OPENCLAW_DOCKER_ALL_PARALLELISM` 控制进程槽位数,而资源上限用于防止重量级 live、npm-install 和多服务通道同时全部启动。默认值为 10 个槽位、`OPENCLAW_DOCKER_ALL_LIVE_LIMIT=6`、`OPENCLAW_DOCKER_ALL_NPM_LIMIT=8` 和 `OPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7`;只有在 Docker 主机有更大余量时,才调整 `OPENCLAW_DOCKER_ALL_WEIGHT_LIMIT` 或 `OPENCLAW_DOCKER_ALL_DOCKER_LIMIT`。运行器默认会执行 Docker 预检查、移除陈旧的 OpenClaw E2E 容器、每 30 秒打印一次状态、将成功通道的耗时存储到 `.artifacts/docker-tests/lane-timings.json`,并在后续运行中利用这些耗时数据优先启动较长的通道。使用 `OPENCLAW_DOCKER_ALL_DRY_RUN=1` 可只打印加权通道清单,而不构建或运行 Docker。
|
||||
- 容器冒烟运行器:`test:docker:openwebui`、`test:docker:onboard`、`test:docker:npm-onboard-channel-agent`、`test:docker:session-runtime-context`、`test:docker:agents-delete-shared-workspace`、`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 模型 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 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,对 Droid/OpenCode 的严格覆盖可通过 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode` 运行)
|
||||
- ACP 绑定冒烟测试:`pnpm test:docker:live-acp-bind`(脚本:`scripts/test-live-acp-bind-docker.sh`;默认覆盖 Claude、Codex 和 Gemini,更严格的 Droid/OpenCode 覆盖可使用 `pnpm test:docker:live-acp-bind:droid` 和 `pnpm test:docker:live-acp-bind:opencode`)
|
||||
- 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 网关 + 开发智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`)
|
||||
- Gateway 网关 + dev 智能体:`pnpm test:docker:live-gateway`(脚本:`scripts/test-live-gateway-models-docker.sh`)
|
||||
- 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 会修复已激活的插件运行时依赖,然后运行一次模拟的 OpenAI 智能体轮次。可使用 `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,使用 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过宿主机构建,或使用 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
|
||||
- 新手引导向导(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 会修复已激活 plugin 的运行时依赖,然后运行一次模拟的 OpenAI 智能体轮次。可通过 `OPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz` 复用预构建 tarball,通过 `OPENCLAW_NPM_ONBOARD_HOST_BUILD=0` 跳过主机构建,或通过 `OPENCLAW_NPM_ONBOARD_CHANNEL=discord` 切换渠道。
|
||||
- Session 运行时上下文冒烟测试:`pnpm test:docker:session-runtime-context` 会验证隐藏运行时上下文 transcript 的持久化,以及 doctor 对受影响的重复 prompt-rewrite 分支的修复。
|
||||
- Bun 全局安装冒烟测试:`bash scripts/e2e/bun-global-install-smoke.sh` 会打包当前工作树,在隔离的 home 中使用 `bun install -g` 安装它,并验证 `openclaw infer image providers --json` 会返回内置 image 提供商而不是卡住。可使用 `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/`。
|
||||
- Installer Docker 冒烟测试:`bash scripts/test-install-sh-docker.sh` 会在其 root、update 和 direct-npm 容器之间共享一个 npm 缓存。更新冒烟默认使用 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` 时,请在本地运行该脚本且不要设置此环境变量。
|
||||
- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离的容器 home 中为两个智能体注入一个工作区,运行 `agents delete --json`,并验证 JSON 有效以及工作区保留行为。可通过 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。
|
||||
- Gateway 网关网络(两个容器、WS 鉴权 + 健康检查):`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`)会通过 Gateway 网关运行一个模拟的 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 bundle MCP 工具(真实 stdio MCP 服务器 + 嵌入式 Pi profile 允许/拒绝冒烟测试):`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`)
|
||||
- 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 缓存。更新冒烟测试默认使用 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` 覆盖,请在本地运行脚本时不要设置该环境变量。
|
||||
- 智能体删除共享工作区 CLI 冒烟测试:`pnpm test:docker:agents-delete-shared-workspace`(脚本:`scripts/e2e/agents-delete-shared-workspace-docker.sh`)默认构建根 Dockerfile 镜像,在隔离的容器 home 中预置两个共享一个工作区的智能体,运行 `agents delete --json`,并验证 JSON 有效以及工作区保留行为。可通过 `OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1` 复用 install-smoke 镜像。
|
||||
- Gateway 网关网络(两个容器,WS 认证 + 健康检查):`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`)会让一个模拟的 OpenAI 服务器通过 Gateway 网关运行,验证 `web_search` 会将 `reasoning.effort` 从 `minimal` 提升到 `low`,然后强制提供商 schema 拒绝,并检查原始细节是否出现在 Gateway 网关日志中。
|
||||
- MCP 渠道桥接(预置 Gateway 网关 + stdio bridge + 原始 Claude 通知帧冒烟测试):`pnpm test:docker:mcp-channels`(脚本:`scripts/e2e/mcp-channels-docker.sh`)
|
||||
- Pi bundle MCP 工具(真实 stdio MCP 服务器 + 内嵌 Pi 配置文件 allow/deny 冒烟测试):`pnpm test:docker:pi-bundle-mcp-tools`(脚本:`scripts/e2e/pi-bundle-mcp-tools-docker.sh`)
|
||||
- Cron/子智能体 MCP 清理(真实 Gateway 网关 + 在隔离 cron 和一次性子智能体运行后拆除 stdio MCP 子进程):`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。完整 Docker 聚合流程会先预打包一次该 tarball,然后将内置渠道检查分片为独立 lane,其中包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的单独更新 lane。直接运行内置 lane 时,可使用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 收窄渠道矩阵,或使用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 收窄更新场景。该 lane 还会验证 `channels.<id>.enabled=false` 和 `plugins.entries.<id>.enabled=false` 会抑制 doctor/运行时依赖修复。
|
||||
- 迭代期间可通过禁用无关场景来收窄内置插件运行时依赖检查,例如:
|
||||
- 配置热重载元数据冒烟测试:`pnpm test:docker:config-reload`(脚本:`scripts/e2e/config-reload-source-docker.sh`)
|
||||
- 内置 plugin 运行时依赖:`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。完整的 Docker 聚合运行会先预打包一次该 tarball,然后将内置渠道检查分片为独立通道,其中包括 Telegram、Discord、Slack、Feishu、memory-lancedb 和 ACPX 的独立更新通道。直接运行内置通道时,可用 `OPENCLAW_BUNDLED_CHANNELS=telegram,slack` 收窄渠道矩阵,或用 `OPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx` 收窄更新场景。该通道还会验证 `channels.<id>.enabled=false` 和 `plugins.entries.<id>.enabled=false` 会抑制 doctor/运行时依赖修复。
|
||||
- 在迭代时收窄内置 plugin 运行时依赖,可禁用无关场景,例如:
|
||||
`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 和 installer Docker 测试保留各自独立的 Dockerfile,因为它们验证的是 package/install 行为,而不是共享的 built-app 运行时。
|
||||
设置后,诸如 `OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE` 之类的测试套件专用镜像覆盖仍会优先生效。当 `OPENCLAW_SKIP_DOCKER_BUILD=1` 指向远程共享镜像时,如果本地还没有该镜像,脚本会先拉取。QR 和安装器 Docker 测试保留各自独立的 Dockerfile,因为它们验证的是打包/安装行为,而不是共享的 built-app 运行时。
|
||||
|
||||
live 模型 Docker 运行器还会以只读方式绑定挂载当前检出,并将其预置到容器内的临时工作目录中。这样可以保持运行时镜像精简,同时仍然让 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 lane 中收窄或排除 gateway live 覆盖时,也要一并透传 `OPENCLAW_LIVE_GATEWAY_*`。
|
||||
`test:docker:openwebui` 是一个更高层级的兼容性冒烟测试:它会启动一个启用了 OpenAI 兼容 HTTP 端点的 OpenClaw gateway 容器,针对该 gateway 启动一个固定版本的 Open WebUI 容器,通过 Open WebUI 完成登录,验证 `/api/models` 暴露了 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一条真实聊天请求。
|
||||
第一次运行可能明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,而 Open WebUI 也可能需要完成自己的冷启动设置。
|
||||
这个 lane 需要可用的 live 模型密钥,而在 Docker 化运行中,`OPENCLAW_PROFILE_FILE`
|
||||
(默认是 `~/.profile`)是提供该密钥的主要方式。
|
||||
成功运行会打印一个简短的 JSON 载荷,例如 `{ "ok": true, "model":
|
||||
"openclaw/default", ... }`。
|
||||
`test:docker:mcp-channels` 是刻意设计为确定性的,不需要真实的 Telegram、Discord 或 iMessage 账号。它会启动一个已注入状态的 Gateway 网关容器,启动第二个容器来生成 `openclaw mcp serve`,然后验证经路由的会话发现、transcript 读取、附件元数据、live 事件队列行为、出站发送路由,以及通过真实 stdio MCP bridge 的 Claude 风格渠道 + 权限通知。通知检查会直接检查原始 stdio MCP 帧,因此这个冒烟测试验证的是 bridge 实际发出的内容,而不仅仅是某个特定客户端 SDK 恰好暴露出来的内容。
|
||||
`test:docker:pi-bundle-mcp-tools` 是确定性的,不需要 live 模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实的 stdio MCP 探针服务器,通过嵌入式 Pi bundle MCP 运行时实例化该服务器,执行工具,然后验证 `coding` 和 `messaging` 会保留 `bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会将其过滤掉。
|
||||
`test:docker:cron-mcp-cleanup` 是确定性的,不需要 live 模型密钥。它会启动一个带有真实 stdio MCP 探针服务器的已注入状态 Gateway 网关,运行一个隔离的 cron 轮次和一个 `/subagents spawn` 一次性子智能体轮次,然后验证 MCP 子进程会在每次运行后退出。
|
||||
这些 live 模型 Docker 运行器还会以只读方式绑定挂载当前检出,并将其预置到容器内的临时工作目录中。这样既能保持运行时镜像轻量,又能让 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 容器,针对该 gateway 启动一个固定版本的 Open WebUI 容器,通过 Open WebUI 登录,验证 `/api/models` 暴露了 `openclaw/default`,然后通过 Open WebUI 的 `/api/chat/completions` 代理发送一条真实聊天请求。
|
||||
首次运行可能会明显更慢,因为 Docker 可能需要拉取 Open WebUI 镜像,而且 Open WebUI 可能需要完成自身的冷启动设置。
|
||||
该通道需要一个可用的 live 模型密钥,而 `OPENCLAW_PROFILE_FILE`(默认 `~/.profile`)是在 Docker 化运行中提供该密钥的主要方式。
|
||||
成功运行会打印一个小型 JSON 负载,例如 `{ "ok": true, "model": "openclaw/default", ... }`。
|
||||
`test:docker:mcp-channels` 是有意设计为确定性的,不需要真实的 Telegram、Discord 或 iMessage 账号。它会启动一个预置的 Gateway 网关容器,再启动第二个容器来运行 `openclaw mcp serve`,然后通过真实的 stdio MCP bridge 验证路由后的会话发现、transcript 读取、附件元数据、live 事件队列行为、出站发送路由,以及 Claude 风格的渠道 + 权限通知。通知检查会直接检查原始 stdio MCP 帧,因此该冒烟测试验证的是 bridge 实际发出的内容,而不只是某个特定客户端 SDK 恰好暴露出来的内容。
|
||||
`test:docker:pi-bundle-mcp-tools` 也是确定性的,不需要 live 模型密钥。它会构建仓库 Docker 镜像,在容器内启动一个真实的 stdio MCP 探测服务器,通过内嵌 Pi bundle MCP 运行时实例化该服务器,执行该工具,然后验证 `coding` 和 `messaging` 会保留 `bundle-mcp` 工具,而 `minimal` 和 `tools.deny: ["bundle-mcp"]` 会将其过滤掉。
|
||||
`test:docker:cron-mcp-cleanup` 也是确定性的,不需要 live 模型密钥。它会启动一个带有真实 stdio MCP 探测服务器的预置 Gateway 网关,运行一个隔离的 cron 轮次和一个 `/subagents spawn` 一次性子智能体轮次,然后验证 MCP 子进程会在每次运行后退出。
|
||||
|
||||
手动 ACP 自然语言线程冒烟测试(不在 CI 中运行):
|
||||
手动 ACP 自然语言线程冒烟测试(非 CI):
|
||||
|
||||
- `bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...`
|
||||
- 保留此脚本用于回归/调试工作流。它未来可能仍会用于 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 的环境变量,使用临时 config/workspace 目录,并且不挂载外部 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`,并在运行测试前 source
|
||||
- `OPENCLAW_DOCKER_PROFILE_ENV_ONLY=1` 用于仅验证从 `OPENCLAW_PROFILE_FILE` source 的环境变量,此时会使用临时 config/workspace 目录,并且不挂载外部 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_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_SKIP_DOCKER_BUILD=1` 用于复用现有的 `openclaw:local-live` 镜像,适合那些不需要重新构建的重跑
|
||||
- `OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1` 用于确保凭证来自 profile 存储(而不是环境变量)
|
||||
- `OPENCLAW_OPENWEBUI_MODEL=...` 用于选择在 Open WebUI 冒烟测试中由 gateway 暴露的模型
|
||||
- `OPENCLAW_OPENWEBUI_PROMPT=...` 用于覆盖 Open WebUI 冒烟测试使用的 nonce 检查提示词
|
||||
@ -549,72 +546,72 @@ Gradle 输出目录,从而避免 Docker live 运行花费数分钟复制与机
|
||||
|
||||
## 文档完整性检查
|
||||
|
||||
文档编辑后运行文档检查:`pnpm check:docs`。
|
||||
当你还需要检查页内标题时,运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。
|
||||
修改文档后运行文档检查:`pnpm check:docs`。
|
||||
当你还需要页内标题检查时,运行完整的 Mintlify 锚点验证:`pnpm docs:check-links:anchors`。
|
||||
|
||||
## 离线回归(对 CI 安全)
|
||||
## 离线回归测试(对 CI 安全)
|
||||
|
||||
这些是在没有真实提供商的情况下进行的“真实流水线”回归:
|
||||
这些是在没有真实提供商的情况下执行的“真实流水线”回归测试:
|
||||
|
||||
- Gateway 网关工具调用(模拟 OpenAI、真实 gateway + Agent loop):`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”)
|
||||
- Gateway 网关向导(WS `wizard.start`/`wizard.next`,强制写入 config + auth):`src/gateway/gateway.test.ts`(用例:“runs wizard over ws and writes auth token config”)
|
||||
|
||||
## 智能体可靠性评估(Skills)
|
||||
|
||||
我们已经有一些对 CI 安全、行为类似“智能体可靠性评估”的测试:
|
||||
我们已经有一些对 CI 安全的测试,行为上类似“智能体可靠性评估”:
|
||||
|
||||
- 通过真实 gateway + Agent loop 进行模拟工具调用(`src/gateway/gateway.test.ts`)。
|
||||
- 验证会话布线和配置效果的端到端向导流程(`src/gateway/gateway.test.ts`)。
|
||||
- 端到端向导流程,用于验证会话接线和配置效果(`src/gateway/gateway.test.ts`)。
|
||||
|
||||
对于 Skills(参见 [Skills](/zh-CN/tools/skills)),目前仍缺少:
|
||||
针对 Skills(见 [Skills](/zh-CN/tools/skills)),目前仍然缺少的是:
|
||||
|
||||
- **决策**:当提示词中列出 Skills 时,智能体是否会选择正确的 Skills(或避免不相关的 Skills)?
|
||||
- **合规性**:智能体在使用前是否会读取 `SKILL.md`,并遵循所要求的步骤/参数?
|
||||
- **工作流契约**:断言工具顺序、会话历史延续以及沙箱边界的多轮场景。
|
||||
- **决策能力:** 当 Skills 在提示中列出时,智能体是否会选择正确的 Skills(或避免无关的 Skills)?
|
||||
- **合规性:** 智能体在使用前是否会读取 `SKILL.md`,并遵循要求的步骤/参数?
|
||||
- **工作流契约:** 多轮场景,用于断言工具顺序、会话历史继承以及沙箱边界。
|
||||
|
||||
未来的评估应当首先保持确定性:
|
||||
未来的评估应优先保持确定性:
|
||||
|
||||
- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、skill 文件读取和会话布线。
|
||||
- 一小套聚焦 skill 的场景(使用 vs 避免、门控、提示注入)。
|
||||
- 只有在对 CI 安全的测试套件到位后,才添加可选的 live 评估(选择加入、由环境变量门控)。
|
||||
- 一个使用模拟提供商的场景运行器,用于断言工具调用 + 顺序、skill 文件读取以及会话接线。
|
||||
- 一小组聚焦于 skill 的场景(使用 vs 避免、门控、提示注入)。
|
||||
- 只有在对 CI 安全的测试套件就绪后,才添加可选的 live 评估(显式启用、受环境变量控制)。
|
||||
|
||||
## 契约测试(插件和渠道形状)
|
||||
## 契约测试(plugin 和 channel 形状)
|
||||
|
||||
契约测试用于验证每个已注册的插件和渠道都符合其接口契约。它们会遍历所有已发现的插件,并运行一组关于形状和行为的断言。默认的 `pnpm test` unit lane 会刻意跳过这些共享接缝和冒烟文件;当你修改共享渠道或提供商表面时,请显式运行契约命令。
|
||||
契约测试用于验证每个已注册 plugin 和 channel 都符合其接口契约。它们会遍历所有已发现的插件,并运行一组关于形状和行为的断言。默认的 `pnpm test` unit 通道会有意跳过这些共享接缝和冒烟文件;当你修改共享的 channel 或 provider 表面时,请显式运行契约命令。
|
||||
|
||||
### 命令
|
||||
|
||||
- 所有契约:`pnpm test:contracts`
|
||||
- 仅渠道契约:`pnpm test:contracts:channels`
|
||||
- 仅提供商契约:`pnpm test:contracts:plugins`
|
||||
- 所有契约测试:`pnpm test:contracts`
|
||||
- 仅渠道契约测试:`pnpm test:contracts:channels`
|
||||
- 仅提供商契约测试:`pnpm test:contracts:plugins`
|
||||
|
||||
### 渠道契约
|
||||
### 渠道契约测试
|
||||
|
||||
位于 `src/channels/plugins/contracts/*.contract.test.ts`:
|
||||
|
||||
- **plugin** - 基本插件形状(id、name、capabilities)
|
||||
- **setup** - 设置向导契约
|
||||
- **session-binding** - 会话绑定行为
|
||||
- **outbound-payload** - 消息载荷结构
|
||||
- **outbound-payload** - 消息负载结构
|
||||
- **inbound** - 入站消息处理
|
||||
- **actions** - 渠道 action 处理器
|
||||
- **actions** - 渠道动作处理器
|
||||
- **threading** - 线程 ID 处理
|
||||
- **directory** - 目录/成员列表 API
|
||||
- **group-policy** - 群组策略执行
|
||||
|
||||
### 提供商状态契约
|
||||
### Provider Status 契约测试
|
||||
|
||||
位于 `src/plugins/contracts/*.contract.test.ts`。
|
||||
|
||||
- **status** - 渠道 Status 探针
|
||||
- **status** - 渠道 Status 探测
|
||||
- **registry** - 插件注册表形状
|
||||
|
||||
### 提供商契约
|
||||
### 提供商契约测试
|
||||
|
||||
位于 `src/plugins/contracts/*.contract.test.ts`:
|
||||
|
||||
- **auth** - 鉴权流程契约
|
||||
- **auth-choice** - 鉴权选择
|
||||
- **auth** - 认证流程契约
|
||||
- **auth-choice** - 认证选项/选择
|
||||
- **catalog** - 模型目录 API
|
||||
- **discovery** - 插件发现
|
||||
- **loader** - 插件加载
|
||||
@ -624,26 +621,26 @@ Gradle 输出目录,从而避免 Docker live 运行花费数分钟复制与机
|
||||
|
||||
### 何时运行
|
||||
|
||||
- 修改 plugin-sdk 导出或子路径后
|
||||
- 添加或修改渠道或提供商插件后
|
||||
- 重构插件注册或发现逻辑后
|
||||
- 修改 `plugin-sdk` 导出或子路径之后
|
||||
- 添加或修改渠道或提供商插件之后
|
||||
- 重构插件注册或发现逻辑之后
|
||||
|
||||
契约测试会在 CI 中运行,不需要真实 API 密钥。
|
||||
契约测试会在 CI 中运行,并且不需要真实 API key。
|
||||
|
||||
## 添加回归测试(指导)
|
||||
|
||||
当你修复了一个在 live 中发现的提供商/模型问题时:
|
||||
|
||||
- 如果可能,添加一个对 CI 安全的回归测试(模拟/桩提供商,或捕获精确的请求形状转换)
|
||||
- 如果它本质上只能在 live 中复现(限流、鉴权策略),就让 live 测试保持收窄,并通过环境变量选择启用
|
||||
- 优先定位能捕获该缺陷的最小层级:
|
||||
- 提供商请求转换/重放缺陷 → 直接模型测试
|
||||
- 如果可能,添加一个对 CI 安全的回归测试(模拟/存根提供商,或捕获精确的请求形状转换)
|
||||
- 如果它本质上只能在 live 中复现(限流、认证策略),那就让 live 测试保持收窄,并通过环境变量显式启用
|
||||
- 优先针对能够捕获该缺陷的最小层级:
|
||||
- 提供商请求转换/回放缺陷 → 直接模型测试
|
||||
- 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 未分类时故意失败,从而避免新类别被静默跳过。
|
||||
- SecretRef 遍历护栏:
|
||||
- `src/secrets/exec-secret-ref-id-parity.test.ts` 会从注册表元数据(`listSecretTargetRegistryEntries()`)中为每个 SecretRef 类派生一个采样目标,然后断言遍历段 exec id 会被拒绝。
|
||||
- 如果你在 `src/secrets/target-registry-data.ts` 中添加新的 `includeInPlan` SecretRef 目标家族,请更新该测试中的 `classifyTargetClass`。该测试会在遇到未分类 target id 时有意失败,从而防止新类别被悄悄跳过。
|
||||
|
||||
## 相关内容
|
||||
|
||||
- [测试 live](/zh-CN/help/testing-live)
|
||||
- [Testing live](/zh-CN/help/testing-live)
|
||||
- [CI](/zh-CN/ci)
|
||||
|
||||
@ -6,66 +6,57 @@ read_when:
|
||||
summary: 在 OpenClaw 中通过 API 密钥或 Codex 订阅使用 OpenAI
|
||||
title: OpenAI
|
||||
x-i18n:
|
||||
generated_at: "2026-04-25T22:38:06Z"
|
||||
generated_at: "2026-04-26T03:01:22Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 524f07dbe30a78a5a4e2ddc373dc6600c07eae4381a1e1b38b8999e27ed932e2
|
||||
source_hash: c44feb226b92f4067283e6a95fa4c38aeb2b6f6107a2f6c6e788ad1f8a899405
|
||||
source_path: providers/openai.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenAI 为 GPT 模型提供开发者 API。OpenClaw 支持三种 OpenAI 系列路由。模型前缀决定所选路由:
|
||||
OpenAI 为 GPT 模型提供开发者 API。OpenClaw 支持三种 OpenAI 系列路线。模型前缀用于选择路线:
|
||||
|
||||
- **API 密钥** — 通过直接 OpenAI Platform 访问并按使用量计费(`openai/*` 模型)
|
||||
- **API 密钥** — 通过直接 OpenAI Platform 访问并按用量计费(`openai/*` 模型)
|
||||
- **通过 PI 的 Codex 订阅** — 使用 ChatGPT/Codex 登录并通过订阅访问(`openai-codex/*` 模型)
|
||||
- **Codex app-server harness** — 原生 Codex app-server 执行(`openai/*` 模型加上 `agents.defaults.embeddedHarness.runtime: "codex"`)
|
||||
- **Codex app-server harness** — 原生 Codex app-server 执行(`openai/*` 模型,外加 `agents.defaults.embeddedHarness.runtime: "codex"`)
|
||||
|
||||
OpenAI 明确支持在 OpenClaw 这样的外部工具和工作流中使用订阅 OAuth。
|
||||
OpenAI 明确支持在 OpenClaw 这类外部工具和工作流中使用订阅 OAuth。
|
||||
|
||||
提供商、模型、运行时和渠道是相互独立的层。如果这些标签
|
||||
开始混淆,请先阅读 [Agent Runtimes](/zh-CN/concepts/agent-runtimes),再
|
||||
修改配置。
|
||||
提供商、模型、运行时和渠道是彼此独立的层。如果你把这些标签混在一起了,请先阅读 [Agent Runtimes](/zh-CN/concepts/agent-runtimes),再修改配置。
|
||||
|
||||
## 快速选择
|
||||
|
||||
| 目标 | 使用方式 | 说明 |
|
||||
| --------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| 直接按 API 密钥计费 | `openai/gpt-5.5` | 设置 `OPENAI_API_KEY` 或运行 OpenAI API 密钥新手引导。 |
|
||||
| 使用 ChatGPT/Codex 订阅认证的 GPT-5.5 | `openai-codex/gpt-5.5` | Codex OAuth 的默认 PI 路由。对于订阅配置,这是最佳首选。 |
|
||||
| 使用原生 Codex app-server 行为的 GPT-5.5 | `openai/gpt-5.5` 加上 `embeddedHarness.runtime: "codex"` | 为该模型引用强制启用 Codex app-server harness。 |
|
||||
| 图像生成或编辑 | `openai/gpt-image-2` | 可配合 `OPENAI_API_KEY` 或 OpenAI Codex OAuth 使用。 |
|
||||
| 直接使用 API 密钥计费 | `openai/gpt-5.5` | 设置 `OPENAI_API_KEY` 或运行 OpenAI API 密钥新手引导。 |
|
||||
| 使用 ChatGPT/Codex 订阅认证的 GPT-5.5 | `openai-codex/gpt-5.5` | Codex OAuth 的默认 PI 路线。是订阅配置的最佳首选。 |
|
||||
| 使用原生 Codex app-server 行为的 GPT-5.5 | `openai/gpt-5.5` 加上 `embeddedHarness.runtime: "codex"` | 为该模型引用强制使用 Codex app-server harness。 |
|
||||
| 图像生成或编辑 | `openai/gpt-image-2` | 可与 `OPENAI_API_KEY` 或 OpenAI Codex OAuth 搭配使用。 |
|
||||
| 透明背景图像 | `openai/gpt-image-1.5` | 使用 `outputFormat=png` 或 `webp`,并设置 `openai.background=transparent`。 |
|
||||
|
||||
<Note>
|
||||
GPT-5.5 同时支持直接 OpenAI Platform API 密钥访问和
|
||||
订阅 / OAuth 路由。对直接 `OPENAI_API_KEY`
|
||||
流量使用 `openai/gpt-5.5`,对通过 PI 的 Codex OAuth 使用 `openai-codex/gpt-5.5`,或
|
||||
对原生 Codex
|
||||
app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/gpt-5.5`。
|
||||
GPT-5.5 同时支持通过直接 OpenAI Platform API 密钥访问,以及订阅 / OAuth 路线。直接使用 `OPENAI_API_KEY` 的流量请使用 `openai/gpt-5.5`,通过 PI 使用 Codex OAuth 请使用 `openai-codex/gpt-5.5`,如果要使用原生 Codex app-server harness,则使用 `openai/gpt-5.5` 并设置 `embeddedHarness.runtime: "codex"`。
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
启用 OpenAI 插件,或选择 `openai-codex/*` 模型,并不会
|
||||
启用内置的 Codex app-server 插件。OpenClaw 只有在你显式选择
|
||||
原生 Codex harness 并设置
|
||||
`embeddedHarness.runtime: "codex"`,或使用旧版 `codex/*` 模型引用时,才会启用该插件。
|
||||
启用 OpenAI 插件,或选择 `openai-codex/*` 模型,并不会启用内置的 Codex app-server 插件。只有当你明确通过 `embeddedHarness.runtime: "codex"` 选择原生 Codex harness,或使用旧版 `codex/*` 模型引用时,OpenClaw 才会启用该插件。
|
||||
</Note>
|
||||
|
||||
## OpenClaw 功能覆盖范围
|
||||
|
||||
| OpenAI 功能 | OpenClaw 界面 | Status |
|
||||
| OpenAI 能力 | OpenClaw 界面 | Status |
|
||||
| ------------------------- | ---------------------------------------------------------- | ------------------------------------------------------ |
|
||||
| 聊天 / Responses | `openai/<model>` 模型提供商 | 是 |
|
||||
| Codex 订阅模型 | 带有 `openai-codex` OAuth 的 `openai-codex/<model>` | 是 |
|
||||
| Codex app-server harness | 带有 `embeddedHarness.runtime: codex` 的 `openai/<model>` | 是 |
|
||||
| 服务器端网页搜索 | 原生 OpenAI Responses 工具 | 是,在启用网页搜索且未固定提供商时 |
|
||||
| Codex app-server harness | 使用 `embeddedHarness.runtime: codex` 的 `openai/<model>` | 是 |
|
||||
| 服务端 Web 搜索 | 原生 OpenAI Responses 工具 | 是,在启用 Web 搜索且未固定提供商时 |
|
||||
| 图像 | `image_generate` | 是 |
|
||||
| 视频 | `video_generate` | 是 |
|
||||
| 文本转语音 | `messages.tts.provider: "openai"` / `tts` | 是 |
|
||||
| 批量语音转文本 | `tools.media.audio` / 媒体理解 | 是 |
|
||||
| 流式语音转文本 | Voice Call `streaming.provider: "openai"` | 是 |
|
||||
| 实时语音 | Voice Call `realtime.provider: "openai"` / Control UI Talk | 是 |
|
||||
| Embeddings | Memory Wiki 嵌入提供商 | 是 |
|
||||
| Embeddings | memory embedding provider | 是 |
|
||||
|
||||
## 入门指南
|
||||
|
||||
@ -73,7 +64,7 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
|
||||
<Tabs>
|
||||
<Tab title="API 密钥(OpenAI Platform)">
|
||||
**最适合:** 直接 API 访问和按使用量计费。
|
||||
**最适合:** 直接 API 访问和按用量计费。
|
||||
|
||||
<Steps>
|
||||
<Step title="获取你的 API 密钥">
|
||||
@ -90,25 +81,22 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
openclaw onboard --openai-api-key "$OPENAI_API_KEY"
|
||||
```
|
||||
</Step>
|
||||
<Step title="验证模型可用">
|
||||
<Step title="验证模型是否可用">
|
||||
```bash
|
||||
openclaw models list --provider openai
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### 路由摘要
|
||||
### 路线摘要
|
||||
|
||||
| Model ref | 路由 | 认证 |
|
||||
| 模型引用 | 路线 | 认证 |
|
||||
|-----------|-------|------|
|
||||
| `openai/gpt-5.5` | 直接 OpenAI Platform API | `OPENAI_API_KEY` |
|
||||
| `openai/gpt-5.4-mini` | 直接 OpenAI Platform API | `OPENAI_API_KEY` |
|
||||
|
||||
<Note>
|
||||
`openai/*` 是直接 OpenAI API 密钥路由,除非你显式强制启用
|
||||
Codex app-server harness。对通过
|
||||
默认 PI 运行器的 Codex OAuth 使用 `openai-codex/*`,或使用带有
|
||||
`embeddedHarness.runtime: "codex"` 的 `openai/gpt-5.5` 进行原生 Codex app-server 执行。
|
||||
除非你明确强制使用 Codex app-server harness,否则 `openai/*` 就是直接 OpenAI API 密钥路线。通过默认 PI runner 使用 Codex OAuth 时,请使用 `openai-codex/*`;若要使用原生 Codex app-server 执行,则使用 `openai/gpt-5.5` 并设置 `embeddedHarness.runtime: "codex"`。
|
||||
</Note>
|
||||
|
||||
### 配置示例
|
||||
@ -121,7 +109,7 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
```
|
||||
|
||||
<Warning>
|
||||
OpenClaw **不**提供 `openai/gpt-5.3-codex-spark`。实时 OpenAI API 请求会拒绝该模型,当前 Codex 目录也同样不提供它。
|
||||
OpenClaw **不**提供 `openai/gpt-5.3-codex-spark`。实时 OpenAI API 请求会拒绝该模型,当前 Codex 目录也没有公开它。
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
@ -141,7 +129,7 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
openclaw models auth login --provider openai-codex
|
||||
```
|
||||
|
||||
对于无头环境或不适合回调的设置,可添加 `--device-code`,通过 ChatGPT 设备码流程登录,而不是使用 localhost 浏览器回调:
|
||||
对于无头环境或不适合回调的设置,添加 `--device-code`,通过 ChatGPT device-code 流程登录,而不是使用 localhost 浏览器回调:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex --device-code
|
||||
@ -152,24 +140,22 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
openclaw config set agents.defaults.model.primary openai-codex/gpt-5.5
|
||||
```
|
||||
</Step>
|
||||
<Step title="验证模型可用">
|
||||
<Step title="验证模型是否可用">
|
||||
```bash
|
||||
openclaw models list --provider openai-codex
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
### 路由摘要
|
||||
### 路线摘要
|
||||
|
||||
| Model ref | 路由 | 认证 |
|
||||
| 模型引用 | 路线 | 认证 |
|
||||
|-----------|-------|------|
|
||||
| `openai-codex/gpt-5.5` | 通过 PI 的 ChatGPT/Codex OAuth | Codex 登录 |
|
||||
| `openai-codex/gpt-5.5` | 通过 PI 使用 ChatGPT/Codex OAuth | Codex 登录 |
|
||||
| `openai/gpt-5.5` + `embeddedHarness.runtime: "codex"` | Codex app-server harness | Codex app-server 认证 |
|
||||
|
||||
<Note>
|
||||
对认证 / 配置文件命令请继续使用 `openai-codex` 提供商 id。
|
||||
`openai-codex/*` 模型前缀也是用于 Codex OAuth 的显式 PI 路由。
|
||||
它不会选择或自动启用内置的 Codex app-server harness。
|
||||
认证 / 配置文件命令请继续使用 `openai-codex` 提供商 id。`openai-codex/*` 模型前缀也是 Codex OAuth 通过 PI 的显式路线。它不会选择或自动启用内置的 Codex app-server harness。
|
||||
</Note>
|
||||
|
||||
### 配置示例
|
||||
@ -181,27 +167,23 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
```
|
||||
|
||||
<Note>
|
||||
新手引导不再从 `~/.codex` 导入 OAuth 材料。请使用浏览器 OAuth(默认)或上面的设备码流程登录——OpenClaw 会在自己的智能体认证存储中管理生成的凭证。
|
||||
新手引导不再从 `~/.codex` 导入 OAuth 材料。请使用浏览器 OAuth(默认)或上面的 device-code 流程登录 —— OpenClaw 会在它自己的智能体认证存储中管理生成的凭证。
|
||||
</Note>
|
||||
|
||||
### Status 指示器
|
||||
|
||||
聊天中的 `/status` 会显示当前会话正在使用的模型运行时。
|
||||
默认 PI harness 显示为 `Runtime: OpenClaw Pi Default`。当选择
|
||||
内置 Codex app-server harness 时,`/status` 会显示
|
||||
`Runtime: OpenAI Codex`。现有会话会保留其记录的 harness id,因此如果你在更改 `embeddedHarness` 后希望 `/status` 反映新的 PI / Codex 选择,请使用
|
||||
`/new` 或 `/reset`。
|
||||
聊天中的 `/status` 会显示当前会话启用了哪个模型运行时。默认 PI harness 会显示为 `Runtime: OpenClaw Pi Default`。选择内置的 Codex app-server harness 后,`/status` 会显示 `Runtime: OpenAI Codex`。现有会话会保留其记录的 harness id,因此如果你修改了 `embeddedHarness`,想让 `/status` 反映新的 PI/Codex 选择,请使用 `/new` 或 `/reset`。
|
||||
|
||||
### 上下文窗口上限
|
||||
|
||||
OpenClaw 将模型元数据和运行时上下文上限视为两个独立的值。
|
||||
|
||||
对于通过 Codex OAuth 的 `openai-codex/gpt-5.5`:
|
||||
对于通过 Codex OAuth 使用的 `openai-codex/gpt-5.5`:
|
||||
|
||||
- 原生 `contextWindow`: `1000000`
|
||||
- 原生 `contextWindow`:`1000000`
|
||||
- 默认运行时 `contextTokens` 上限:`272000`
|
||||
|
||||
实践中,这个较小的默认上限通常具有更好的延迟和质量表现。你可以用 `contextTokens` 覆盖它:
|
||||
默认的较小上限在实践中具有更好的延迟和质量表现。你可以使用 `contextTokens` 覆盖它:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -216,34 +198,30 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
```
|
||||
|
||||
<Note>
|
||||
使用 `contextWindow` 声明模型的原生元数据。使用 `contextTokens` 限制运行时上下文预算。
|
||||
使用 `contextWindow` 声明原生模型元数据。使用 `contextTokens` 限制运行时上下文预算。
|
||||
</Note>
|
||||
|
||||
### 目录恢复
|
||||
|
||||
OpenClaw 会在上游 Codex 目录元数据存在时,使用其中的 `gpt-5.5`
|
||||
元数据。如果实时 Codex 发现阶段在账户已认证的情况下遗漏了 `openai-codex/gpt-5.5` 这一行,
|
||||
OpenClaw 会合成该 OAuth 模型条目,这样 cron、子智能体以及已配置默认模型的运行就不会因
|
||||
`Unknown model` 而失败。
|
||||
当上游 Codex 目录元数据存在时,OpenClaw 会对 `gpt-5.5` 使用该元数据。如果实时 Codex 发现过程中遗漏了 `openai-codex/gpt-5.5` 这一行,而账户已完成认证,OpenClaw 会合成这一 OAuth 模型行,这样 cron、子智能体以及已配置的默认模型运行就不会因 `Unknown model` 而失败。
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 图像生成
|
||||
|
||||
内置的 `openai` 插件通过 `image_generate` 工具注册图像生成。
|
||||
它同时支持 OpenAI API 密钥图像生成和通过同一个 `openai/gpt-image-2` 模型引用进行的 Codex OAuth 图像
|
||||
生成。
|
||||
内置的 `openai` 插件通过 `image_generate` 工具注册图像生成功能。
|
||||
它同时支持使用 OpenAI API 密钥进行图像生成,以及通过同一个 `openai/gpt-image-2` 模型引用使用 Codex OAuth 进行图像生成。
|
||||
|
||||
| 功能 | OpenAI API 密钥 | Codex OAuth |
|
||||
| 能力 | OpenAI API 密钥 | Codex OAuth |
|
||||
| ------------------------- | ---------------------------------- | ------------------------------------ |
|
||||
| Model ref | `openai/gpt-image-2` | `openai/gpt-image-2` |
|
||||
| 模型引用 | `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 | 在安全时映射为受支持的尺寸 |
|
||||
| 尺寸覆盖 | 支持,包括 2K/4K 尺寸 | 支持,包括 2K/4K 尺寸 |
|
||||
| 宽高比 / 分辨率 | 不会转发到 OpenAI Images API | 在安全时映射到受支持的尺寸 |
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -256,22 +234,12 @@ app-server harness 使用带有 `embeddedHarness.runtime: "codex"` 的 `openai/g
|
||||
```
|
||||
|
||||
<Note>
|
||||
有关共享工具参数、提供商选择和故障切换行为,请参阅 [图像生成](/zh-CN/tools/image-generation)。
|
||||
共享工具参数、提供商选择和故障转移行为,请参阅 [图像生成](/zh-CN/tools/image-generation)。
|
||||
</Note>
|
||||
|
||||
`gpt-image-2` 是 OpenAI 文生图生成和图像
|
||||
编辑的默认模型。`gpt-image-1.5`、`gpt-image-1` 和 `gpt-image-1-mini` 仍可作为
|
||||
显式模型覆盖使用。对于透明背景
|
||||
PNG/WebP 输出,请使用 `openai/gpt-image-1.5`;当前 `gpt-image-2` API 会拒绝
|
||||
`background: "transparent"`。
|
||||
`gpt-image-2` 是 OpenAI 文生图生成和图像编辑的默认模型。`gpt-image-1.5`、`gpt-image-1` 和 `gpt-image-1-mini` 仍可作为显式模型覆盖使用。透明背景 PNG/WebP 输出请使用 `openai/gpt-image-1.5`;当前 `gpt-image-2` API 会拒绝 `background: "transparent"`。
|
||||
|
||||
对于透明背景请求,智能体应调用 `image_generate`,并设置
|
||||
`model: "openai/gpt-image-1.5"`、`outputFormat: "png"` 或 `"webp"`,以及
|
||||
`background: "transparent"`;旧版 `openai.background` 提供商选项
|
||||
仍然可用。OpenClaw 还会通过将默认的 `openai/gpt-image-2` 透明
|
||||
请求重写为 `gpt-image-1.5` 来保护公共 OpenAI 和
|
||||
OpenAI Codex OAuth 路由;Azure 和自定义的 OpenAI 兼容端点则保留
|
||||
其已配置的 deployment / model 名称。
|
||||
对于透明背景请求,智能体应使用 `image_generate`,并设置 `model: "openai/gpt-image-1.5"`、`outputFormat: "png"` 或 `"webp"`,以及 `background: "transparent"`;较早的 `openai.background` 提供商选项仍然可用。OpenClaw 还会通过将默认的 `openai/gpt-image-2` 透明背景请求重写为 `gpt-image-1.5`,来保护公开的 OpenAI 和 OpenAI Codex OAuth 路线;Azure 和自定义 OpenAI 兼容端点会保留它们已配置的 deployment / model 名称。
|
||||
|
||||
同样的设置也适用于无头 CLI 运行:
|
||||
|
||||
@ -284,20 +252,11 @@ openclaw infer image generate \
|
||||
--json
|
||||
```
|
||||
|
||||
从输入文件开始时,对
|
||||
`openclaw infer image edit` 也使用相同的 `--output-format` 和 `--background` 标志。
|
||||
`--openai-background` 仍然作为 OpenAI 专用别名保留。
|
||||
从输入文件开始时,对 `openclaw infer image edit` 也使用相同的 `--output-format` 和 `--background` 标志。
|
||||
`--openai-background` 仍然可作为 OpenAI 专用别名使用。
|
||||
|
||||
对于 Codex OAuth 安装,继续使用相同的 `openai/gpt-image-2` 引用。当
|
||||
配置了 `openai-codex` OAuth 配置文件时,OpenClaw 会解析该存储的 OAuth
|
||||
访问令牌,并通过 Codex Responses 后端发送图像请求。它
|
||||
不会先尝试 `OPENAI_API_KEY`,也不会在该请求中静默回退到 API 密钥。
|
||||
当你希望改为使用直接 OpenAI Images API
|
||||
路由时,请使用 API 密钥、
|
||||
自定义 base URL 或 Azure 端点显式配置 `models.providers.openai`。
|
||||
如果该自定义图像端点位于受信任的局域网 / 私有地址上,还需同时设置
|
||||
`browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true`;若未显式启用此选项,
|
||||
OpenClaw 会继续阻止访问私有 / 内部的 OpenAI 兼容图像端点。
|
||||
对于 Codex OAuth 安装,请继续使用相同的 `openai/gpt-image-2` 引用。当配置了 `openai-codex` OAuth 配置文件时,OpenClaw 会解析该已存储的 OAuth 访问令牌,并通过 Codex Responses 后端发送图像请求。它不会先尝试 `OPENAI_API_KEY`,也不会在该请求上静默回退到 API 密钥。如果你想改用直接 OpenAI Images API 路线,请显式配置 `models.providers.openai`,并提供 API 密钥、自定义 base URL 或 Azure 端点。
|
||||
如果该自定义图像端点位于受信任的 LAN / 私有地址上,还要设置 `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork: true`;除非显式启用此项,否则 OpenClaw 会继续阻止私有 / 内部 OpenAI 兼容图像端点。
|
||||
|
||||
生成:
|
||||
|
||||
@ -319,15 +278,15 @@ OpenClaw 会继续阻止访问私有 / 内部的 OpenAI 兼容图像端点。
|
||||
|
||||
## 视频生成
|
||||
|
||||
内置的 `openai` 插件通过 `video_generate` 工具注册视频生成。
|
||||
内置的 `openai` 插件通过 `video_generate` 工具注册视频生成功能。
|
||||
|
||||
| 功能 | 值 |
|
||||
| 能力 | 值 |
|
||||
| ---------------- | --------------------------------------------------------------------------------- |
|
||||
| 默认模型 | `openai/sora-2` |
|
||||
| 模式 | 文本生成视频、图像生成视频、单视频编辑 |
|
||||
| 参考输入 | 1 张图像或 1 个视频 |
|
||||
| 尺寸覆盖 | 支持 |
|
||||
| 其他覆盖项 | `aspectRatio`、`resolution`、`audio`、`watermark` 会被忽略,并给出工具警告 |
|
||||
| 其他覆盖项 | `aspectRatio`、`resolution`、`audio`、`watermark` 会被忽略,并附带工具警告 |
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -340,16 +299,16 @@ OpenClaw 会继续阻止访问私有 / 内部的 OpenAI 兼容图像端点。
|
||||
```
|
||||
|
||||
<Note>
|
||||
有关共享工具参数、提供商选择和故障切换行为,请参阅 [视频生成](/zh-CN/tools/video-generation)。
|
||||
共享工具参数、提供商选择和故障转移行为,请参阅 [视频生成](/zh-CN/tools/video-generation)。
|
||||
</Note>
|
||||
|
||||
## GPT-5 提示词贡献
|
||||
## GPT-5 提示贡献
|
||||
|
||||
OpenClaw 会为跨提供商的 GPT-5 系列运行添加共享的 GPT-5 提示词贡献。它按模型 id 应用,因此 `openai-codex/gpt-5.5`、`openai/gpt-5.5`、`openrouter/openai/gpt-5.5`、`opencode/gpt-5.5` 以及其他兼容的 GPT-5 引用都会收到相同的覆盖层。较早的 GPT-4.x 模型则不会。
|
||||
OpenClaw 为跨提供商的 GPT-5 系列运行添加了一个共享的 GPT-5 提示贡献。它按模型 id 应用,因此 `openai-codex/gpt-5.5`、`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 行为和心跳覆盖层,因此即使 Codex 接管了其余 harness 提示词,通过 `embeddedHarness.runtime: "codex"` 强制使用的 `openai/gpt-5.x` 会话也会保留相同的后续执行和主动心跳指导。
|
||||
内置的原生 Codex harness 通过 Codex app-server 开发者指令使用相同的 GPT-5 行为和心跳叠加层,因此,即使 Codex 接管了 harness 提示的其余部分,强制通过 `embeddedHarness.runtime: "codex"` 运行的 `openai/gpt-5.x` 会话仍会保留相同的执行跟进和主动心跳指引。
|
||||
|
||||
GPT-5 贡献添加了一个带标签的行为契约,用于规范人格持续性、执行安全、工具纪律、输出形状、完成检查和验证。特定于渠道的回复和静默消息行为仍保留在共享的 OpenClaw 系统提示词和出站传递策略中。对于匹配的模型,GPT-5 指导始终启用。友好交互风格层是独立的,并且可配置。
|
||||
GPT-5 贡献增加了一个带标签的行为契约,涵盖人格持久性、执行安全性、工具纪律、输出形态、完成检查和验证。渠道特定的回复行为和静默消息行为仍保留在共享的 OpenClaw 系统提示和出站传递策略中。GPT-5 指引始终会为匹配的模型启用。友好交互风格层则是独立的,并且可配置。
|
||||
|
||||
| 值 | 效果 |
|
||||
| ---------------------- | ------------------------------------------- |
|
||||
@ -379,30 +338,30 @@ GPT-5 贡献添加了一个带标签的行为契约,用于规范人格持续
|
||||
</Tabs>
|
||||
|
||||
<Tip>
|
||||
运行时值不区分大小写,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。
|
||||
运行时对值大小写不敏感,因此 `"Off"` 和 `"off"` 都会禁用友好风格层。
|
||||
</Tip>
|
||||
|
||||
<Note>
|
||||
当未设置共享的 `agents.defaults.promptOverlays.gpt5.personality` 配置时,旧版 `plugins.entries.openai.config.personality` 仍会作为兼容性回退继续读取。
|
||||
当共享设置 `agents.defaults.promptOverlays.gpt5.personality` 未设置时,仍会读取旧版 `plugins.entries.openai.config.personality` 作为兼容性回退。
|
||||
</Note>
|
||||
|
||||
## 语音与语音识别
|
||||
## 语音和语音识别
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="语音合成(TTS)">
|
||||
内置的 `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.voice` | `coral` |
|
||||
| 速度 | `messages.tts.providers.openai.speed` | (未设置) |
|
||||
| 指令 | `messages.tts.providers.openai.instructions` | (未设置,仅 `gpt-4o-mini-tts`) |
|
||||
| 格式 | `messages.tts.providers.openai.responseFormat` | 语音便笺使用 `opus`,文件使用 `mp3` |
|
||||
| 指令 | `messages.tts.providers.openai.instructions` | (未设置,仅适用于 `gpt-4o-mini-tts`) |
|
||||
| 格式 | `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
|
||||
{
|
||||
@ -423,17 +382,14 @@ GPT-5 贡献添加了一个带标签的行为契约,用于规范人格持续
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="语音转文本">
|
||||
内置的 `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
|
||||
{
|
||||
@ -453,37 +409,36 @@ GPT-5 贡献添加了一个带标签的行为契约,用于规范人格持续
|
||||
}
|
||||
```
|
||||
|
||||
当共享音频媒体配置或每次调用的转录请求中提供了
|
||||
language 和 prompt 提示时,OpenClaw 会将它们转发给 OpenAI。
|
||||
当共享音频媒体配置或每次调用的转录请求提供语言和提示时,这些提示会被转发给 OpenAI。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="实时转录">
|
||||
内置的 `openai` 插件会为 Voice Call 插件注册实时转录功能。
|
||||
内置的 `openai` 插件为 Voice Call 插件注册了实时转录功能。
|
||||
|
||||
| 设置 | 配置路径 | 默认值 |
|
||||
|---------|------------|---------|
|
||||
| 模型 | `plugins.entries.voice-call.config.streaming.providers.openai.model` | `gpt-4o-transcribe` |
|
||||
| 语言 | `...openai.language` | (未设置) |
|
||||
| Prompt | `...openai.prompt` | (未设置) |
|
||||
| 提示 | `...openai.prompt` | (未设置) |
|
||||
| 静音时长 | `...openai.silenceDurationMs` | `800` |
|
||||
| VAD 阈值 | `...openai.vadThreshold` | `0.5` |
|
||||
| API 密钥 | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` |
|
||||
|
||||
<Note>
|
||||
使用 WebSocket 连接到 `wss://api.openai.com/v1/realtime`,并采用 G.711 u-law(`g711_ulaw` / `audio/pcmu`)音频。这个流式提供商用于 Voice Call 的实时转录路径;Discord 语音目前仍会录制短片段,并改用批量 `tools.media.audio` 转录路径。
|
||||
使用到 `wss://api.openai.com/v1/realtime` 的 WebSocket 连接,以及 G.711 u-law(`g711_ulaw` / `audio/pcmu`)音频。这个流式提供商用于 Voice Call 的实时转录路径;Discord 语音目前仍会录制短片段,并改用批量 `tools.media.audio` 转录路径。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="实时语音">
|
||||
内置的 `openai` 插件会为 Voice Call 插件注册实时语音功能。
|
||||
内置的 `openai` 插件为 Voice Call 插件注册了实时语音功能。
|
||||
|
||||
| 设置 | 配置路径 | 默认值 |
|
||||
|---------|------------|---------|
|
||||
| 模型 | `plugins.entries.voice-call.config.realtime.providers.openai.model` | `gpt-realtime-1.5` |
|
||||
| 语音 | `...openai.voice` | `alloy` |
|
||||
| 温度 | `...openai.temperature` | `0.8` |
|
||||
| 音色 | `...openai.voice` | `alloy` |
|
||||
| Temperature | `...openai.temperature` | `0.8` |
|
||||
| VAD 阈值 | `...openai.vadThreshold` | `0.5` |
|
||||
| 静音时长 | `...openai.silenceDurationMs` | `500` |
|
||||
| API 密钥 | `...openai.apiKey` | 回退到 `OPENAI_API_KEY` |
|
||||
@ -497,30 +452,21 @@ GPT-5 贡献添加了一个带标签的行为契约,用于规范人格持续
|
||||
|
||||
## Azure OpenAI 端点
|
||||
|
||||
内置的 `openai` 提供商可以通过覆盖 base URL,将图像
|
||||
生成请求指向 Azure OpenAI 资源。在图像生成路径上,OpenClaw
|
||||
会检测 `models.providers.openai.baseUrl` 中的 Azure 主机名,并自动切换到
|
||||
Azure 的请求格式。
|
||||
内置的 `openai` 提供商可以通过覆盖 base URL,将图像生成请求发送到 Azure OpenAI 资源。在图像生成路径上,OpenClaw 会检测 `models.providers.openai.baseUrl` 中的 Azure 主机名,并自动切换到 Azure 的请求格式。
|
||||
|
||||
<Note>
|
||||
实时语音使用单独的配置路径
|
||||
(`plugins.entries.voice-call.config.realtime.providers.openai.azureEndpoint`),
|
||||
不会受到 `models.providers.openai.baseUrl` 的影响。请参阅 [语音与语音识别](#voice-and-speech) 下 **实时
|
||||
语音** 折叠项中的 Azure
|
||||
设置。
|
||||
实时语音使用单独的配置路径(`plugins.entries.voice-call.config.realtime.providers.openai.azureEndpoint`),不受 `models.providers.openai.baseUrl` 影响。其 Azure 设置请参阅 [语音和语音识别](#voice-and-speech) 下的 **实时语音** 折叠面板。
|
||||
</Note>
|
||||
|
||||
在以下情况下使用 Azure OpenAI:
|
||||
|
||||
- 你已经拥有 Azure OpenAI 订阅、配额或企业协议
|
||||
- 你已经有 Azure OpenAI 订阅、配额或企业协议
|
||||
- 你需要 Azure 提供的区域数据驻留或合规控制
|
||||
- 你希望将流量保留在现有 Azure 租户内部
|
||||
- 你希望将流量保留在现有 Azure 租户内
|
||||
|
||||
### 配置
|
||||
|
||||
要通过内置 `openai` 提供商使用 Azure 图像生成,请将
|
||||
`models.providers.openai.baseUrl` 指向你的 Azure 资源,并将 `apiKey` 设置为
|
||||
Azure OpenAI 密钥(而不是 OpenAI Platform 密钥):
|
||||
要通过内置的 `openai` 提供商使用 Azure 图像生成,请将 `models.providers.openai.baseUrl` 指向你的 Azure 资源,并将 `apiKey` 设置为 Azure OpenAI 密钥(而不是 OpenAI Platform 密钥):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -535,34 +481,29 @@ Azure OpenAI 密钥(而不是 OpenAI Platform 密钥):
|
||||
}
|
||||
```
|
||||
|
||||
OpenClaw 会识别以下 Azure 主机后缀,并用于 Azure 图像生成
|
||||
路由:
|
||||
OpenClaw 会将以下 Azure 主机后缀识别为 Azure 图像生成路线:
|
||||
|
||||
- `*.openai.azure.com`
|
||||
- `*.services.ai.azure.com`
|
||||
- `*.cognitiveservices.azure.com`
|
||||
|
||||
对于识别出的 Azure 主机上的图像生成请求,OpenClaw 会:
|
||||
对于发送到已识别 Azure 主机的图像生成请求,OpenClaw 会:
|
||||
|
||||
- 发送 `api-key` 请求头,而不是 `Authorization: Bearer`
|
||||
- 使用以 deployment 为作用域的路径(`/openai/deployments/{deployment}/...`)
|
||||
- 使用按 deployment 作用域划分的路径(`/openai/deployments/{deployment}/...`)
|
||||
- 为每个请求附加 `?api-version=...`
|
||||
- 对 Azure 图像生成调用使用默认 600 秒请求超时。
|
||||
每次调用的 `timeoutMs` 值仍会覆盖该默认值。
|
||||
每次调用的 `timeoutMs` 值仍会覆盖这个默认值。
|
||||
|
||||
其他 base URL(公共 OpenAI、OpenAI 兼容代理)仍保留标准的
|
||||
OpenAI 图像请求格式。
|
||||
其他 base URL(公开 OpenAI、OpenAI 兼容代理)会继续使用标准 OpenAI 图像请求格式。
|
||||
|
||||
<Note>
|
||||
`openai` 提供商图像生成路径的 Azure 路由要求
|
||||
OpenClaw 2026.4.22 或更高版本。更早版本会将任何自定义
|
||||
`openai.baseUrl` 视为公共 OpenAI 端点,并且在 Azure
|
||||
图像 deployment 上失败。
|
||||
`openai` 提供商图像生成路径的 Azure 路由要求 OpenClaw 2026.4.22 或更高版本。更早版本会把任何自定义 `openai.baseUrl` 都当作公开 OpenAI 端点处理,因此在 Azure 图像 deployment 上会失败。
|
||||
</Note>
|
||||
|
||||
### API 版本
|
||||
|
||||
设置 `AZURE_OPENAI_API_VERSION` 可固定 Azure 图像生成路径所使用的特定 Azure 预览版或 GA 版本:
|
||||
设置 `AZURE_OPENAI_API_VERSION`,可为 Azure 图像生成路径固定特定的 Azure 预览版或正式版:
|
||||
|
||||
```bash
|
||||
export AZURE_OPENAI_API_VERSION="2024-12-01-preview"
|
||||
@ -572,62 +513,47 @@ export AZURE_OPENAI_API_VERSION="2024-12-01-preview"
|
||||
|
||||
### 模型名称就是 deployment 名称
|
||||
|
||||
Azure OpenAI 会将模型绑定到 deployment。对于通过内置 `openai` 提供商路由的 Azure 图像生成请求,OpenClaw 中的 `model` 字段
|
||||
必须是你在 Azure 门户中配置的**Azure deployment 名称**,而不是
|
||||
公共 OpenAI 模型 id。
|
||||
Azure OpenAI 会将模型绑定到 deployment。对于通过内置 `openai` 提供商路由的 Azure 图像生成请求,OpenClaw 中的 `model` 字段必须是你在 Azure 门户中配置的 **Azure deployment 名称**,而不是公开的 OpenAI 模型 id。
|
||||
|
||||
如果你创建了一个名为 `gpt-image-2-prod`、用于提供 `gpt-image-2` 的 deployment:
|
||||
如果你创建了一个名为 `gpt-image-2-prod`、服务于 `gpt-image-2` 的 deployment:
|
||||
|
||||
```
|
||||
/tool image_generate model=openai/gpt-image-2-prod prompt="A clean poster" size=1024x1024 count=1
|
||||
```
|
||||
|
||||
同样的 deployment 名称规则也适用于通过
|
||||
内置 `openai` 提供商路由的图像生成调用。
|
||||
同样的 deployment 名称规则也适用于通过内置 `openai` 提供商路由的图像生成调用。
|
||||
|
||||
### 区域可用性
|
||||
|
||||
Azure 图像生成目前仅在部分区域
|
||||
可用(例如 `eastus2`、`swedencentral`、`polandcentral`、`westus3`、
|
||||
`uaenorth`)。在创建
|
||||
deployment 之前,请先查看 Microsoft 当前的区域列表,并确认你的区域提供该特定模型。
|
||||
Azure 图像生成目前仅在部分区域可用(例如 `eastus2`、`swedencentral`、`polandcentral`、`westus3`、`uaenorth`)。在创建 deployment 之前,请先检查 Microsoft 当前的区域列表,并确认你的区域提供该特定模型。
|
||||
|
||||
### 参数差异
|
||||
|
||||
Azure OpenAI 和公共 OpenAI 并不总是接受相同的图像参数。
|
||||
Azure 可能会拒绝公共 OpenAI 允许的某些选项(例如
|
||||
`gpt-image-2` 上的某些 `background` 值),或仅在特定模型版本中提供这些选项。这些差异来自 Azure 和底层模型,而不是
|
||||
OpenClaw。如果 Azure 请求因验证错误而失败,请在
|
||||
Azure 门户中检查你的特定 deployment 和 API 版本所支持的参数集。
|
||||
Azure OpenAI 和公开 OpenAI 并不总是接受相同的图像参数。Azure 可能会拒绝公开 OpenAI 允许的某些选项(例如 `gpt-image-2` 上的某些 `background` 值),或者仅在特定模型版本上提供这些选项。这些差异来自 Azure 和底层模型,而不是 OpenClaw。如果 Azure 请求因验证错误而失败,请在 Azure 门户中检查你的特定 deployment 和 API 版本支持的参数集。
|
||||
|
||||
<Note>
|
||||
Azure OpenAI 使用原生传输和兼容行为,但不会接收
|
||||
OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-configuration) 下的 **原生与 OpenAI 兼容
|
||||
路由** 折叠项。
|
||||
Azure OpenAI 使用原生传输和兼容行为,但不会接收 OpenClaw 的隐藏归因请求头 —— 请参阅 [高级配置](#advanced-configuration) 下 **原生与 OpenAI 兼容路线** 折叠面板。
|
||||
|
||||
对于 Azure 上的聊天或 Responses 流量(不仅限于图像生成),请使用
|
||||
新手引导流程或专用 Azure 提供商配置——仅靠 `openai.baseUrl` 并不会自动采用 Azure 的 API / 认证格式。另有一个独立的
|
||||
`azure-openai-responses/*` 提供商;请参阅
|
||||
下方的服务器端压缩折叠项。
|
||||
对于 Azure 上的聊天或 Responses 流量(图像生成之外),请使用新手引导流程或专用的 Azure 提供商配置 —— 单独设置 `openai.baseUrl` 并不会采用 Azure API / 认证格式。另有一个单独的 `azure-openai-responses/*` 提供商;请参阅下方的服务端压缩折叠面板。
|
||||
</Note>
|
||||
|
||||
## 高级配置
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="传输(WebSocket 与 SSE)">
|
||||
OpenClaw 对 `openai/*` 和 `openai-codex/*` 都采用 WebSocket 优先,并在失败时回退到 SSE(`"auto"`)。
|
||||
对于 `openai/*` 和 `openai-codex/*`,OpenClaw 都默认使用 WebSocket 优先,并在失败时回退到 SSE(`"auto"`)。
|
||||
|
||||
在 `"auto"` 模式下,OpenClaw 会:
|
||||
- 在回退到 SSE 之前重试一次早期 WebSocket 失败
|
||||
- 失败后,将 WebSocket 标记为降级状态约 60 秒,并在冷却期间使用 SSE
|
||||
- 在回退到 SSE 之前,重试一次早期 WebSocket 失败
|
||||
- 在一次失败后,将 WebSocket 标记为降级约 60 秒,并在冷却期间使用 SSE
|
||||
- 为重试和重连附加稳定的会话和轮次标识请求头
|
||||
- 在不同传输变体之间规范化使用计数器(`input_tokens` / `prompt_tokens`)
|
||||
- 跨传输变体标准化用量计数器(`input_tokens` / `prompt_tokens`)
|
||||
|
||||
| 值 | 行为 |
|
||||
|-------|----------|
|
||||
| `"auto"`(默认) | WebSocket 优先,SSE 回退 |
|
||||
| `"sse"` | 仅强制使用 SSE |
|
||||
| `"websocket"` | 仅强制使用 WebSocket |
|
||||
| `"sse"` | 强制仅使用 SSE |
|
||||
| `"websocket"` | 强制仅使用 WebSocket |
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -653,7 +579,7 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="WebSocket 预热">
|
||||
OpenClaw 默认对 `openai/*` 和 `openai-codex/*` 启用 WebSocket 预热,以降低首次轮次延迟。
|
||||
OpenClaw 默认对 `openai/*` 和 `openai-codex/*` 启用 WebSocket 预热,以降低首轮延迟。
|
||||
|
||||
```json5
|
||||
// 禁用预热
|
||||
@ -673,12 +599,12 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="快速模式">
|
||||
OpenClaw 为 `openai/*` 和 `openai-codex/*` 提供共享的快速模式开关:
|
||||
OpenClaw 为 `openai/*` 和 `openai-codex/*` 提供了共享的快速模式开关:
|
||||
|
||||
- **聊天 / UI:** `/fast status|on|off`
|
||||
- **配置:** `agents.defaults.models["<provider>/<model>"].params.fastMode`
|
||||
|
||||
启用后,OpenClaw 会将快速模式映射到 OpenAI 优先处理(`service_tier = "priority"`)。现有的 `service_tier` 值会被保留,快速模式不会重写 `reasoning` 或 `text.verbosity`。
|
||||
启用后,OpenClaw 会将快速模式映射为 OpenAI 优先处理(`service_tier = "priority"`)。现有的 `service_tier` 值会被保留,快速模式不会改写 `reasoning` 或 `text.verbosity`。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -693,13 +619,13 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
```
|
||||
|
||||
<Note>
|
||||
会话级覆盖优先于配置。在 Sessions UI 中清除会话覆盖后,该会话会恢复为配置的默认值。
|
||||
会话覆盖优先于配置。在 Sessions UI 中清除会话覆盖后,会话会恢复到配置的默认值。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="优先处理(service_tier)">
|
||||
OpenAI 的 API 通过 `service_tier` 提供优先处理能力。可在 OpenClaw 中按模型设置:
|
||||
OpenAI 的 API 通过 `service_tier` 提供优先处理。在 OpenClaw 中按模型设置:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -716,23 +642,23 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
支持的值:`auto`、`default`、`flex`、`priority`。
|
||||
|
||||
<Warning>
|
||||
`serviceTier` 仅会转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由这两个提供商之一,OpenClaw 会保持 `service_tier` 不变。
|
||||
`serviceTier` 仅会转发到原生 OpenAI 端点(`api.openai.com`)和原生 Codex 端点(`chatgpt.com/backend-api`)。如果你通过代理路由任一提供商,OpenClaw 会保持 `service_tier` 不变。
|
||||
</Warning>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="服务器端压缩(Responses API)">
|
||||
对于直接 OpenAI Responses 模型(`api.openai.com` 上的 `openai/*`),OpenAI 插件的 Pi-harness 流包装器会自动启用服务器端压缩:
|
||||
<Accordion title="服务端压缩(Responses API)">
|
||||
对于直接 OpenAI Responses 模型(`api.openai.com` 上的 `openai/*`),OpenAI 插件的 Pi-harness 流包装器会自动启用服务端压缩:
|
||||
|
||||
- 强制设置 `store: true`(除非模型兼容层设置了 `supportsStore: false`)
|
||||
- 强制设置 `store: true`(除非模型兼容性设置了 `supportsStore: false`)
|
||||
- 注入 `context_management: [{ type: "compaction", compact_threshold: ... }]`
|
||||
- 默认 `compact_threshold`:`contextWindow` 的 70%(不可用时为 `80000`)
|
||||
|
||||
这适用于内置 Pi harness 路径,以及嵌入式运行使用的 OpenAI 提供商钩子。原生 Codex app-server harness 通过 Codex 管理自己的上下文,并使用 `agents.defaults.embeddedHarness.runtime` 单独配置。
|
||||
这适用于内置 Pi harness 路径,也适用于嵌入式运行使用的 OpenAI 提供商钩子。原生 Codex app-server harness 通过 Codex 管理自己的上下文,并通过 `agents.defaults.embeddedHarness.runtime` 单独配置。
|
||||
|
||||
<Tabs>
|
||||
<Tab title="显式启用">
|
||||
适用于 Azure OpenAI Responses 之类的兼容端点:
|
||||
对于 Azure OpenAI Responses 等兼容端点很有用:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -784,12 +710,12 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
`responsesServerCompaction` 仅控制 `context_management` 注入。直接 OpenAI Responses 模型仍会强制设置 `store: true`,除非兼容层设置了 `supportsStore: false`。
|
||||
`responsesServerCompaction` 仅控制 `context_management` 注入。直接 OpenAI Responses 模型仍会强制 `store: true`,除非兼容性设置了 `supportsStore: false`。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="严格智能体 GPT 模式">
|
||||
<Accordion title="严格智能体式 GPT 模式">
|
||||
对于 `openai/*` 上的 GPT-5 系列运行,OpenClaw 可以使用更严格的嵌入式执行契约:
|
||||
|
||||
```json5
|
||||
@ -803,32 +729,33 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
```
|
||||
|
||||
使用 `strict-agentic` 时,OpenClaw 会:
|
||||
- 当有工具操作可用时,不再将“仅计划”的轮次视为成功推进
|
||||
- 通过“立即行动”引导重试该轮
|
||||
- 在重大工作中自动启用 `update_plan`
|
||||
- 如果模型持续规划而不执行操作,则显示显式的阻塞状态
|
||||
- 当有可用工具操作时,不再将“仅规划”的轮次视为成功进展
|
||||
- 使用“立即行动”的引导重试该轮次
|
||||
- 对实质性工作自动启用 `update_plan`
|
||||
- 如果模型持续规划而不执行操作,则显式显示阻塞状态
|
||||
|
||||
<Note>
|
||||
仅适用于 OpenAI 和 Codex 的 GPT-5 系列运行。其他提供商和较旧模型系列保持默认行为。
|
||||
仅适用于 OpenAI 和 Codex 的 GPT-5 系列运行。其他提供商和更旧的模型系列会保留默认行为。
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="原生与 OpenAI 兼容路由">
|
||||
OpenClaw 会将直接 OpenAI、Codex 和 Azure OpenAI 端点与通用 OpenAI 兼容 `/v1` 代理区别对待:
|
||||
<Accordion title="原生与 OpenAI 兼容路线">
|
||||
OpenClaw 会区别对待直接 OpenAI、Codex 和 Azure OpenAI 端点,以及通用的 OpenAI 兼容 `/v1` 代理:
|
||||
|
||||
**原生路由**(`openai/*`、Azure OpenAI):
|
||||
**原生路线**(`openai/*`、Azure OpenAI):
|
||||
- 仅对支持 OpenAI `none` effort 的模型保留 `reasoning: { effort: "none" }`
|
||||
- 对拒绝 `reasoning.effort: "none"` 的模型或代理省略禁用式 reasoning
|
||||
- 对拒绝 `reasoning.effort: "none"` 的模型或代理省略禁用推理设置
|
||||
- 默认将工具 schema 设为严格模式
|
||||
- 仅在已验证的原生主机上附加隐藏归因请求头
|
||||
- 保留 OpenAI 专用请求整形(`service_tier`、`store`、reasoning 兼容、prompt-cache 提示)
|
||||
- 保留 OpenAI 专用的请求整形(`service_tier`、`store`、reasoning 兼容性、提示缓存提示)
|
||||
|
||||
**代理 / 兼容路由:**
|
||||
**代理 / 兼容路线:**
|
||||
- 使用更宽松的兼容行为
|
||||
- 从非原生 `openai-completions` 负载中移除 Completions `store`
|
||||
- 接受用于 OpenAI 兼容 Completions 代理的高级 `params.extra_body` / `params.extraBody` 透传 JSON
|
||||
- 不强制严格工具 schema 或原生专用请求头
|
||||
- 为 OpenAI 兼容 Completions 代理接受高级 `params.extra_body` / `params.extraBody` 透传 JSON
|
||||
- 为 vLLM 等 OpenAI 兼容 Completions 代理接受 `params.chat_template_kwargs`
|
||||
- 不强制严格工具 schema 或仅限原生的请求头
|
||||
|
||||
Azure OpenAI 使用原生传输和兼容行为,但不会接收隐藏归因请求头。
|
||||
|
||||
@ -839,7 +766,7 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="模型选择" href="/zh-CN/concepts/model-providers" icon="layers">
|
||||
选择提供商、模型引用和故障切换行为。
|
||||
选择提供商、模型引用和故障转移行为。
|
||||
</Card>
|
||||
<Card title="图像生成" href="/zh-CN/tools/image-generation" icon="image">
|
||||
共享图像工具参数和提供商选择。
|
||||
@ -847,7 +774,7 @@ OpenClaw 的隐藏归因请求头——请参阅 [高级配置](#advanced-config
|
||||
<Card title="视频生成" href="/zh-CN/tools/video-generation" icon="video">
|
||||
共享视频工具参数和提供商选择。
|
||||
</Card>
|
||||
<Card title="OAuth 与认证" href="/zh-CN/gateway/authentication" icon="key">
|
||||
认证细节和凭证复用规则。
|
||||
<Card title="OAuth 和认证" href="/zh-CN/gateway/authentication" icon="key">
|
||||
认证详情和凭证复用规则。
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
---
|
||||
read_when:
|
||||
- 你想让 OpenClaw 对接本地 vLLM 服务器运行
|
||||
- 你想使用带有自有模型的 OpenAI 兼容 `/v1` 端点ிகள to=final code omitted
|
||||
summary: 将 OpenClaw 与 vLLM 一起运行(OpenAI 兼容本地服务器)
|
||||
- 你希望使用兼容 OpenAI 的 `/v1` 端点,并接入你自己的模型
|
||||
summary: 使用 vLLM(兼容 OpenAI 的本地服务器)运行 OpenClaw
|
||||
title: vLLM
|
||||
x-i18n:
|
||||
generated_at: "2026-04-23T21:02:39Z"
|
||||
generated_at: "2026-04-26T03:01:23Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: f0296422a926c83b1ab5ffdac7857e34253b624f0d8756c02d49f8805869a219
|
||||
source_hash: fbf424cb532f2b3e188c39545b187e5db6274ff2fadc01c9e4cb0901dbe9824c
|
||||
source_path: providers/vllm.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
vLLM 可以通过**OpenAI 兼容** HTTP API 提供开源模型(以及某些自定义模型)服务。OpenClaw 使用 `openai-completions` API 连接到 vLLM。
|
||||
vLLM 可以通过 **兼容 OpenAI** 的 HTTP API 提供开源模型(以及一些自定义模型)。OpenClaw 使用 `openai-completions` API 连接到 vLLM。
|
||||
|
||||
当你通过 `VLLM_API_KEY` 选择启用,且未定义显式的 `models.providers.vllm` 条目时,OpenClaw 还可以**自动发现** vLLM 中可用的模型(如果你的服务器不强制认证,则任意值都可用)。
|
||||
当你设置 `VLLM_API_KEY` 以启用此功能时(如果你的服务器不强制验证,任意值都可以),并且你没有定义显式的 `models.providers.vllm` 条目,OpenClaw 还可以从 vLLM **自动发现** 可用模型。
|
||||
|
||||
OpenClaw 将 `vllm` 视为支持
|
||||
流式使用量统计的本地 OpenAI 兼容提供商,因此状态/上下文 token 计数可以根据
|
||||
OpenClaw 将 `vllm` 视为本地的兼容 OpenAI 的提供商,并支持
|
||||
流式使用量统计,因此状态 / 上下文令牌计数可以根据
|
||||
`stream_options.include_usage` 响应进行更新。
|
||||
|
||||
| 属性 | 值 |
|
||||
| ---------------- | ---------------------------------------- |
|
||||
| 提供商 ID | `vllm` |
|
||||
| API | `openai-completions`(OpenAI 兼容) |
|
||||
| 身份验证 | `VLLM_API_KEY` 环境变量 |
|
||||
| API | `openai-completions`(兼容 OpenAI) |
|
||||
| 认证 | `VLLM_API_KEY` 环境变量 |
|
||||
| 默认 base URL | `http://127.0.0.1:8000/v1` |
|
||||
|
||||
## 入门指南
|
||||
|
||||
<Steps>
|
||||
<Step title="启动带有 OpenAI 兼容服务器的 vLLM">
|
||||
你的 base URL 应暴露 `/v1` 端点(例如 `/v1/models`、`/v1/chat/completions`)。vLLM 通常运行在:
|
||||
<Step title="使用兼容 OpenAI 的服务器启动 vLLM">
|
||||
你的 base URL 应该暴露 `/v1` 端点(例如 `/v1/models`、`/v1/chat/completions`)。vLLM 通常运行在:
|
||||
|
||||
```
|
||||
http://127.0.0.1:8000/v1
|
||||
@ -40,15 +40,15 @@ OpenClaw 将 `vllm` 视为支持
|
||||
|
||||
</Step>
|
||||
<Step title="设置 API 密钥环境变量">
|
||||
如果你的服务器不强制认证,则任意值都可用:
|
||||
如果你的服务器不强制认证,任意值都可以:
|
||||
|
||||
```bash
|
||||
export VLLM_API_KEY="vllm-local"
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="选择模型">
|
||||
请替换为你的某个 vLLM 模型 ID:
|
||||
<Step title="选择一个模型">
|
||||
替换为你的某个 vLLM 模型 ID:
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -70,7 +70,7 @@ OpenClaw 将 `vllm` 视为支持
|
||||
|
||||
## 模型发现(隐式提供商)
|
||||
|
||||
当设置了 `VLLM_API_KEY`(或存在 auth profile),并且你**没有**定义 `models.providers.vllm` 时,OpenClaw 会查询:
|
||||
当设置了 `VLLM_API_KEY`(或存在认证配置文件),并且你**没有**定义 `models.providers.vllm` 时,OpenClaw 会查询:
|
||||
|
||||
```
|
||||
GET http://127.0.0.1:8000/v1/models
|
||||
@ -84,11 +84,12 @@ GET http://127.0.0.1:8000/v1/models
|
||||
|
||||
## 显式配置(手动模型)
|
||||
|
||||
在以下情况下,请使用显式配置:
|
||||
在以下情况下使用显式配置:
|
||||
|
||||
- vLLM 运行在不同的主机或端口上
|
||||
- 你想固定 `contextWindow` 或 `maxTokens` 值
|
||||
- 你的服务器需要真实的 API 密钥(或你想控制标头)
|
||||
- 你想固定 `contextWindow` 或 `maxTokens` 的值
|
||||
- 你的服务器需要真实的 API 密钥(或者你想控制请求头)
|
||||
- 你连接到受信任的 loopback、LAN 或 Tailscale vLLM 端点
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -98,6 +99,7 @@ GET http://127.0.0.1:8000/v1/models
|
||||
baseUrl: "http://127.0.0.1:8000/v1",
|
||||
apiKey: "${VLLM_API_KEY}",
|
||||
api: "openai-completions",
|
||||
request: { allowPrivateNetwork: true },
|
||||
models: [
|
||||
{
|
||||
id: "your-model-id",
|
||||
@ -119,17 +121,56 @@ GET http://127.0.0.1:8000/v1/models
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="代理式行为">
|
||||
vLLM 被视为代理式 OpenAI 兼容 `/v1` 后端,而不是原生
|
||||
vLLM 被视为代理式的兼容 OpenAI 的 `/v1` 后端,而不是原生
|
||||
OpenAI 端点。这意味着:
|
||||
|
||||
| 行为 | 是否应用? |
|
||||
|----------|----------|
|
||||
| 原生 OpenAI 请求整形 | 否 |
|
||||
| 原生 OpenAI 请求塑形 | 否 |
|
||||
| `service_tier` | 不发送 |
|
||||
| Responses `store` | 不发送 |
|
||||
| Prompt-cache 提示 | 不发送 |
|
||||
| OpenAI 推理兼容载荷整形 | 不应用 |
|
||||
| 隐藏的 OpenClaw 归属标头 | 不会注入到自定义 base URL 上 |
|
||||
| 响应 `store` | 不发送 |
|
||||
| 提示缓存提示 | 不发送 |
|
||||
| OpenAI 推理兼容载荷塑形 | 不应用 |
|
||||
| 隐藏的 OpenClaw 归因请求头 | 在自定义 base URL 上不注入 |
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Nemotron 3 思考控制">
|
||||
vLLM / Nemotron 3 可以使用聊天模板 kwargs 来控制推理内容是
|
||||
作为隐藏推理返回,还是作为可见答案文本返回。当 OpenClaw 会话
|
||||
使用 `vllm/nemotron-3-*` 且关闭 thinking 时,OpenClaw 会发送:
|
||||
|
||||
```json
|
||||
{
|
||||
"chat_template_kwargs": {
|
||||
"enable_thinking": false,
|
||||
"force_nonempty_content": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
要自定义这些值,请在模型参数下设置 `chat_template_kwargs`。
|
||||
如果你还设置了 `params.extra_body.chat_template_kwargs`,该值将拥有
|
||||
最终优先级,因为 `extra_body` 是对请求体的最后覆盖。
|
||||
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"vllm/nemotron-3-super": {
|
||||
params: {
|
||||
chat_template_kwargs: {
|
||||
enable_thinking: false,
|
||||
force_nonempty_content: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -144,6 +185,7 @@ GET http://127.0.0.1:8000/v1/models
|
||||
baseUrl: "http://192.168.1.50:9000/v1",
|
||||
apiKey: "${VLLM_API_KEY}",
|
||||
api: "openai-completions",
|
||||
request: { allowPrivateNetwork: true },
|
||||
models: [
|
||||
{
|
||||
id: "my-custom-model",
|
||||
@ -167,32 +209,36 @@ GET http://127.0.0.1:8000/v1/models
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="服务器不可达">
|
||||
请检查 vLLM 服务器是否正在运行且可访问:
|
||||
检查 vLLM 服务器是否正在运行并且可访问:
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8000/v1/models
|
||||
```
|
||||
|
||||
如果你看到连接错误,请验证主机、端口,以及 vLLM 是否以 OpenAI 兼容服务器模式启动。
|
||||
如果你看到连接错误,请确认主机、端口,以及 vLLM 是否以兼容 OpenAI 的服务器模式启动。
|
||||
对于显式的 loopback、LAN 或 Tailscale 端点,还需要设置
|
||||
`models.providers.vllm.request.allowPrivateNetwork: true`;提供商
|
||||
请求默认会阻止私有网络 URL,除非该提供商被
|
||||
显式信任。
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="请求出现身份验证错误">
|
||||
如果请求因身份验证错误而失败,请设置一个与你服务器配置匹配的真实 `VLLM_API_KEY`,或在 `models.providers.vllm` 下显式配置该提供商。
|
||||
<Accordion title="请求出现认证错误">
|
||||
如果请求因认证错误而失败,请设置与你的服务器配置匹配的真实 `VLLM_API_KEY`,或者在 `models.providers.vllm` 下显式配置该提供商。
|
||||
|
||||
<Tip>
|
||||
如果你的 vLLM 服务器不强制认证,则任意非空 `VLLM_API_KEY` 都可以作为 OpenClaw 的启用信号。
|
||||
如果你的 vLLM 服务器不强制认证,任意非空的 `VLLM_API_KEY` 值都可以作为 OpenClaw 的启用信号。
|
||||
</Tip>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="未发现任何模型">
|
||||
自动发现要求必须设置 `VLLM_API_KEY`,**并且**不存在显式的 `models.providers.vllm` 配置条目。如果你已经手动定义了该提供商,OpenClaw 会跳过发现,只使用你声明的模型。
|
||||
自动发现要求设置 `VLLM_API_KEY`,**并且**不能存在显式的 `models.providers.vllm` 配置条目。如果你已经手动定义了该提供商,OpenClaw 会跳过发现,只使用你声明的模型。
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
<Warning>
|
||||
更多帮助请参见:[故障排除](/zh-CN/help/troubleshooting) 和 [常见问题](/zh-CN/help/faq)。
|
||||
更多帮助:[故障排除](/zh-CN/help/troubleshooting) 和 [常见问题](/zh-CN/help/faq)。
|
||||
</Warning>
|
||||
|
||||
## 相关内容
|
||||
@ -202,10 +248,10 @@ GET http://127.0.0.1:8000/v1/models
|
||||
选择提供商、模型引用和故障切换行为。
|
||||
</Card>
|
||||
<Card title="OpenAI" href="/zh-CN/providers/openai" icon="bolt">
|
||||
原生 OpenAI 提供商以及 OpenAI 兼容路由行为。
|
||||
原生 OpenAI provider 和兼容 OpenAI 的路由行为。
|
||||
</Card>
|
||||
<Card title="OAuth 和身份验证" href="/zh-CN/gateway/authentication" icon="key">
|
||||
身份验证细节和凭证复用规则。
|
||||
<Card title="OAuth 和认证" href="/zh-CN/gateway/authentication" icon="key">
|
||||
认证细节和凭证复用规则。
|
||||
</Card>
|
||||
<Card title="故障排除" href="/zh-CN/help/troubleshooting" icon="wrench">
|
||||
常见问题及其解决方法。
|
||||
|
||||
@ -1,186 +1,272 @@
|
||||
---
|
||||
read_when:
|
||||
- 通过 ACP 运行编码 harness
|
||||
- 在消息渠道上设置与对话绑定的 ACP 会话
|
||||
- 将消息渠道对话绑定到持久化 ACP 会话
|
||||
- 在消息渠道上设置绑定到会话的 ACP 会话
|
||||
- 将消息渠道会话绑定到持久化 ACP 会话
|
||||
- 排查 ACP 后端和插件连接问题
|
||||
- 调试 ACP 完成结果传递或智能体间循环问题
|
||||
- 从聊天中操作 `/acp` 命令
|
||||
summary: 对 Claude Code、Cursor、Gemini CLI、显式 Codex ACP 回退、OpenClaw ACP 和其他 harness 智能体使用 ACP 运行时会话
|
||||
- 从聊天中操作 /acp 命令
|
||||
summary: 对 Claude Code、Cursor、Gemini CLI、显式 Codex ACP 回退、OpenClaw ACP 以及其他 harness 智能体使用 ACP 运行时会话
|
||||
title: ACP 智能体
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T02:42:44Z"
|
||||
generated_at: "2026-04-26T03:01:51Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 8dd7a28e6f9cae50d0381373b4aa944c5040e42153916cd586a2def2ad2a84d7
|
||||
source_hash: 17cff2c29c897da80ef44c4a9640a323eff595e2e960e72b085a09a690566a37
|
||||
source_path: tools/acp-agents.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
[Agent Client Protocol(ACP)](https://agentclientprotocol.com/) 会话让 OpenClaw 能够通过 ACP 后端插件运行外部编码 harness(例如 Pi、Claude Code、Cursor、Copilot、Droid、OpenClaw ACP、OpenCode、Gemini CLI 以及其他受支持的 ACPX harness)。
|
||||
[Agent Client Protocol(ACP)](https://agentclientprotocol.com/) 会话让 OpenClaw 能够通过 ACP 后端插件运行外部编码 harness(例如 Pi、Claude Code、Cursor、Copilot、Droid、OpenClaw ACP、OpenCode、Gemini CLI,以及其他受支持的 ACPX harness)。
|
||||
|
||||
如果你用自然语言请求 OpenClaw 在当前对话中绑定或控制 Codex,并且内置的 `codex` 插件已启用,OpenClaw 应该使用原生 Codex 应用服务器插件(`/codex bind`、`/codex threads`、`/codex resume`、`/codex steer`、`/codex stop`),而不是 ACP。如果你明确请求 `/acp`、ACP、acpx 或 ACP 适配器测试,OpenClaw 仍然可以通过 ACP 路由 Codex。每次 ACP 会话启动都会被跟踪为一个[后台任务](/zh-CN/automation/tasks)。
|
||||
如果你用自然语言要求 OpenClaw 在当前会话中绑定或控制 Codex,并且已启用内置的 `codex` 插件,OpenClaw 应使用原生 Codex app-server 插件(`/codex bind`、`/codex threads`、`/codex resume`、`/codex steer`、`/codex stop`),而不是 ACP。如果你明确要求 `/acp`、ACP、acpx 或 ACP 适配器测试,OpenClaw 仍然可以通过 ACP 路由 Codex。每次 ACP 会话启动都会作为一个[后台任务](/zh-CN/automation/tasks)进行跟踪。
|
||||
|
||||
如果你用自然语言请求 OpenClaw “在一个线程中启动 Claude Code” 或使用其他外部 harness,OpenClaw 应该将该请求路由到 ACP 运行时(而不是原生子智能体运行时)。
|
||||
如果你用自然语言要求 OpenClaw “在一个线程中启动 Claude Code”或使用其他外部 harness,OpenClaw 应将该请求路由到 ACP 运行时(而不是原生子智能体运行时)。
|
||||
|
||||
如果你希望 Codex 或 Claude Code 作为外部 MCP 客户端直接连接到现有的 OpenClaw 渠道对话,请使用 [`openclaw mcp serve`](/zh-CN/cli/mcp),而不是 ACP。
|
||||
如果你希望 Codex 或 Claude Code 作为外部 MCP 客户端直接连接
|
||||
到现有的 OpenClaw 渠道会话,请使用 [`openclaw mcp serve`](/zh-CN/cli/mcp)
|
||||
而不是 ACP。
|
||||
|
||||
## 我想看哪个页面?
|
||||
## 我想要哪个页面?
|
||||
|
||||
这里有三个相邻但容易混淆的功能界面:
|
||||
这里有三个相邻但很容易混淆的入口:
|
||||
|
||||
| 你想要… | 使用这个 | 说明 |
|
||||
| 你想要…… | 使用这个 | 说明 |
|
||||
| ----------------------------------------------------------------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 在当前对话中绑定或控制 Codex | `/codex bind`、`/codex threads` | 当 `codex` 插件启用时,这是原生 Codex 应用服务器路径;包括绑定聊天回复、图片转发、模型 / 快速 / 权限设置、停止和引导控制。ACP 是显式回退方案 |
|
||||
| 通过 OpenClaw 运行 Claude Code、Gemini CLI、显式 Codex ACP 或其他外部 harness | 本页:ACP 智能体 | 绑定聊天的会话、`/acp spawn`、`sessions_spawn({ runtime: "acp" })`、后台任务、运行时控制 |
|
||||
| 在当前会话中绑定或控制 Codex | `/codex bind`、`/codex threads` | 启用 `codex` 插件时使用原生 Codex app-server 路径;包括已绑定聊天回复、图片转发、模型 / 快速 / 权限控制、停止和引导控制。ACP 是显式回退方案 |
|
||||
| 通过 OpenClaw 运行 Claude Code、Gemini CLI、显式 Codex ACP 或其他外部 harness | 本页:ACP 智能体 | 聊天绑定会话、`/acp spawn`、`sessions_spawn({ runtime: "acp" })`、后台任务、运行时控制 |
|
||||
| 将一个 OpenClaw Gateway 网关会话作为 ACP 服务器暴露给编辑器或客户端 | [`openclaw acp`](/zh-CN/cli/acp) | 桥接模式。IDE / 客户端通过 stdio / WebSocket 使用 ACP 与 OpenClaw 通信 |
|
||||
| 复用本地 AI CLI 作为纯文本回退模型 | [CLI Backends](/zh-CN/gateway/cli-backends) | 不是 ACP。没有 OpenClaw 工具、没有 ACP 控制、也没有 harness 运行时 |
|
||||
| 将本地 AI CLI 复用为纯文本回退模型 | [CLI 后端](/zh-CN/gateway/cli-backends) | 不是 ACP。没有 OpenClaw 工具、没有 ACP 控制、没有 harness 运行时 |
|
||||
|
||||
## 这开箱即用吗?
|
||||
## 开箱即用吗?
|
||||
|
||||
通常是的。全新安装默认启用内置的 `acpx` 运行时插件,并带有一个插件本地固定版本的 `acpx` 二进制文件,OpenClaw 会在启动时探测并自我修复。运行 `/acp doctor` 可进行就绪性检查。
|
||||
通常可以。全新安装默认启用内置的 `acpx` 运行时插件,并附带一个插件本地固定版本的 `acpx` 二进制文件,OpenClaw 会在启动时探测并自我修复。运行 `/acp doctor` 可进行就绪性检查。
|
||||
|
||||
首次运行时的常见注意事项:
|
||||
首次运行的注意事项:
|
||||
|
||||
- 如果设置了 `plugins.allow`,它就是一个限制性的插件清单,必须包含 `acpx`;否则内置默认项会被有意阻止,且 `/acp doctor` 会报告缺失的 allowlist 条目。
|
||||
- 目标 harness 适配器(Codex、Claude 等)可能会在你首次使用它们时通过 `npx` 按需拉取。
|
||||
- 该 harness 的供应商认证仍然必须存在于主机上。
|
||||
- 如果主机没有 npm 或网络访问能力,首次运行时的适配器拉取将失败,直到缓存被预热或适配器通过其他方式安装。
|
||||
- 如果设置了 `plugins.allow`,它就是一个严格限制的插件清单,必须包含 `acpx`;否则内置默认项会被有意阻止,且 `/acp doctor` 会报告缺少 allowlist 条目。
|
||||
- 目标 harness 适配器(Codex、Claude 等)可能会在你首次使用时按需通过 `npx` 获取。
|
||||
- 该 harness 对应的厂商凭证仍然必须已存在于主机上。
|
||||
- 如果主机没有 npm 或无法访问网络,首次运行时的适配器获取将失败,直到缓存被预热或通过其他方式安装该适配器。
|
||||
|
||||
## 运维操作手册
|
||||
## 支持的 harness 目标
|
||||
|
||||
通过聊天使用 `/acp` 的快速流程:
|
||||
使用内置 `acpx` 后端时,可将以下 harness id 用作 `/acp spawn <id>` 或
|
||||
`sessions_spawn({ runtime: "acp", agentId: "<id>" })` 的目标:
|
||||
|
||||
| Harness id | 典型后端 | 说明 |
|
||||
| ---------- | ---------------------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `claude` | Claude Code ACP adapter | 需要主机上存在 Claude Code 凭证。 |
|
||||
| `codex` | Codex ACP adapter | 仅当原生 `/codex` 不可用或明确请求 ACP 时,才作为显式 ACP 回退。 |
|
||||
| `copilot` | GitHub Copilot ACP adapter | 需要 Copilot CLI / 运行时凭证。 |
|
||||
| `cursor` | Cursor CLI ACP(`cursor-agent acp`) | 如果本地安装暴露了不同的 ACP 入口点,请覆盖 acpx 命令。 |
|
||||
| `droid` | Factory Droid CLI | 需要 Factory / Droid 凭证,或在 harness 环境中设置 `FACTORY_API_KEY`。 |
|
||||
| `gemini` | Gemini CLI ACP adapter | 需要 Gemini CLI 凭证或 API 密钥设置。 |
|
||||
| `opencode` | OpenCode ACP adapter | 需要 OpenCode CLI / 提供商凭证。 |
|
||||
| `openclaw` | 通过 `openclaw acp` 实现的 OpenClaw Gateway 网关桥接 | 让支持 ACP 的 harness 能够回连到 OpenClaw Gateway 网关会话。 |
|
||||
| `pi` | Pi / 内嵌 OpenClaw 运行时 | 用于 OpenClaw 原生 harness 实验。 |
|
||||
| `iflow` | iFlow CLI | 适配器可用性和模型控制取决于已安装的 CLI。 |
|
||||
| `kilocode` | Kilo Code CLI | 适配器可用性和模型控制取决于已安装的 CLI。 |
|
||||
| `kimi` | Kimi / Moonshot CLI | 需要主机上存在 Kimi / Moonshot 凭证。 |
|
||||
| `kiro` | Kiro CLI | 适配器可用性和模型控制取决于已安装的 CLI。 |
|
||||
| `qwen` | Qwen Code / Qwen CLI | 需要主机上存在兼容 Qwen 的凭证。 |
|
||||
|
||||
自定义 acpx 智能体别名可以在 acpx 本身中配置,但 OpenClaw 策略
|
||||
在分发前仍会检查 `acp.allowedAgents` 以及任何 `agents.list[].runtime.acp.agent`
|
||||
映射。
|
||||
|
||||
## 运行时前提条件
|
||||
|
||||
ACP 会启动一个真实的外部 harness 进程。OpenClaw 负责路由、
|
||||
后台任务状态、传递、绑定和策略;而 harness 负责其自身的
|
||||
提供商登录、模型目录、文件系统行为和原生工具。
|
||||
|
||||
在责怪 OpenClaw 之前,请先确认:
|
||||
|
||||
- `/acp doctor` 报告后端已启用且健康。
|
||||
- 设置了 allowlist 时,目标 id 已被 `acp.allowedAgents` 允许。
|
||||
- harness 命令可以在 Gateway 网关主机上启动。
|
||||
- 该 harness 的提供商凭证已存在(`claude`、`codex`、`gemini`、
|
||||
`opencode`、`droid` 等)。
|
||||
- 所选模型对该 harness 可用。模型 id 不能在不同
|
||||
harness 之间通用。
|
||||
- 请求的 `cwd` 存在且可访问,或者省略 `cwd` 让后端使用其默认值。
|
||||
- 权限模式与工作内容匹配。非交互式会话无法点击
|
||||
原生权限提示,因此大量写入 / 执行的编码任务通常需要一个
|
||||
能够无头继续执行的 ACPX 权限配置。
|
||||
|
||||
OpenClaw 插件工具和内置 OpenClaw 工具默认不会暴露给 ACP
|
||||
harness。只有在你希望 harness 直接调用这些工具时,才在
|
||||
[ACP 智能体 — 设置](/zh-CN/tools/acp-agents-setup) 中启用显式 MCP 桥接。
|
||||
|
||||
## 运维手册
|
||||
|
||||
在聊天中使用 `/acp` 的快速流程:
|
||||
|
||||
1. **启动** — `/acp spawn claude --bind here`、`/acp spawn gemini --mode persistent --thread auto`,或显式使用 `/acp spawn codex --bind here`
|
||||
2. 在绑定的对话或线程中**工作**(或者显式指定会话键)。
|
||||
2. 在已绑定的会话或线程中**工作**(或者显式指定会话键)。
|
||||
3. **检查状态** — `/acp status`
|
||||
4. **调整** — `/acp model <provider/model>`、`/acp permissions <profile>`、`/acp timeout <seconds>`
|
||||
5. 在不替换上下文的情况下进行**引导** — `/acp steer tighten logging and continue`
|
||||
5. **引导**而不替换上下文 — `/acp steer tighten logging and continue`
|
||||
6. **停止** — `/acp cancel`(当前轮次)或 `/acp close`(会话 + 绑定)
|
||||
|
||||
当原生 Codex 插件启用时,应路由到该插件的自然语言触发方式:
|
||||
生命周期细节:
|
||||
|
||||
- 启动会创建或恢复一个 ACP 运行时会话,在
|
||||
OpenClaw 会话存储中记录 ACP 元数据,并且当运行由父级拥有时
|
||||
可能会创建一个后台任务。
|
||||
- 绑定后的后续消息会直接发送到 ACP 会话,直到绑定被
|
||||
关闭、失焦、重置或过期。
|
||||
- Gateway 网关命令保持在本地执行。`/acp ...`、`/status` 和 `/unfocus` 绝不会
|
||||
作为普通提示文本发送给已绑定的 ACP harness。
|
||||
- `cancel` 会在后端支持取消时中止当前轮次;
|
||||
它不会删除绑定或会话元数据。
|
||||
- `close` 会从 OpenClaw 的视角结束 ACP 会话并移除
|
||||
绑定。如果 harness 支持恢复,它仍可能保留自己的上游历史记录。
|
||||
- 空闲运行时工作进程在 `acp.runtime.ttlMinutes` 之后符合清理条件;
|
||||
已存储的会话元数据仍可通过 `/acp sessions` 使用。
|
||||
|
||||
启用原生 Codex 插件时,应路由到该插件的自然语言触发示例:
|
||||
|
||||
- “将这个 Discord 渠道绑定到 Codex。”
|
||||
- “将这个聊天附加到 Codex 线程 `<id>`。”
|
||||
- “显示 Codex 线程,然后绑定这一个。”
|
||||
- “把这个聊天附加到 Codex 线程 `<id>`。”
|
||||
- “先显示 Codex 线程,然后绑定这个。”
|
||||
|
||||
原生 Codex 对话绑定是默认的聊天控制路径。OpenClaw 动态工具仍通过 OpenClaw 执行,而 Codex 原生工具(例如 shell / apply-patch)则在 Codex 内执行。对于 Codex 原生工具事件,OpenClaw 会按轮次注入一个原生钩子中继,使插件钩子能够阻止 `before_tool_call`、观察 `after_tool_call`,并通过 OpenClaw 审批路由 Codex 的 `PermissionRequest` 事件。Codex 的 `Stop` 钩子会被中继到 OpenClaw 的 `before_agent_finalize`,插件可以在那里请求模型在 Codex 最终生成答案之前再执行一次。该中继刻意保持保守:它不会修改 Codex 原生工具参数,也不会重写 Codex 线程记录。只有当你想使用 ACP 运行时 / 会话模型时,才使用显式 ACP。嵌入式 Codex 支持边界记录在 [Codex harness v1 support contract](/zh-CN/plugins/codex-harness#v1-support-contract) 中。
|
||||
原生 Codex 会话绑定是默认的聊天控制路径。OpenClaw
|
||||
动态工具仍通过 OpenClaw 执行,而 Codex 原生工具(例如
|
||||
shell / apply-patch)则在 Codex 内部执行。对于 Codex 原生工具事件,OpenClaw
|
||||
会按轮次注入一个原生 hook 中继,以便插件钩子能够阻止
|
||||
`before_tool_call`、观察 `after_tool_call`,并通过 OpenClaw 审批
|
||||
路由 Codex `PermissionRequest` 事件。Codex `Stop` 钩子
|
||||
会被中继到 OpenClaw `before_agent_finalize`,在此插件可以请求
|
||||
在 Codex 最终生成答案之前再进行一次模型调用。该中继刻意保持保守:
|
||||
它不会修改 Codex 原生工具参数,也不会重写 Codex
|
||||
线程记录。只有当你想要 ACP 运行时 / 会话模型时,才使用显式 ACP。内嵌 Codex 支持边界记录在
|
||||
[Codex harness v1 支持契约](/zh-CN/plugins/codex-harness#v1-support-contract)
|
||||
中。
|
||||
|
||||
应路由到 ACP 运行时的自然语言触发方式:
|
||||
应路由到 ACP 运行时的自然语言触发示例:
|
||||
|
||||
- “将这个作为一次性的 Claude Code ACP 会话运行,并总结结果。”
|
||||
- “对此任务使用 Gemini CLI 在线程中处理,然后后续都保留在同一个线程里。”
|
||||
- “通过 ACP 在后台线程中运行 Codex。”
|
||||
- “把这个作为一次性的 Claude Code ACP 会话运行,并总结结果。”
|
||||
- “这个任务使用 Gemini CLI 在线程中处理,然后把后续消息保留在同一个线程里。”
|
||||
- “在线程后台通过 ACP 运行 Codex。”
|
||||
|
||||
OpenClaw 会选择 `runtime: "acp"`,解析 harness `agentId`,在支持时绑定到当前对话或线程,并将后续消息路由到该会话,直到关闭或过期。只有在明确请求 ACP / acpx,或者请求的操作无法使用原生 Codex 插件时,Codex 才会走这条路径。
|
||||
OpenClaw 会选择 `runtime: "acp"`,解析 harness `agentId`,在支持时绑定到当前会话或线程,并将后续消息路由到该会话,直到关闭 / 过期。只有在明确要求 ACP / acpx,或针对所请求操作原生 Codex 插件不可用时,Codex 才会走这一路径。
|
||||
|
||||
对于 `sessions_spawn`,只有当 ACP 已启用、请求方未处于沙箱隔离中,并且已加载 ACP 运行时后端时,才会公布 `runtime: "acp"`。它面向 ACP harness id,例如 `codex`、`claude`、`droid`、`gemini` 或 `opencode`。不要传入来自 `agents_list` 的普通 OpenClaw 配置智能体 id,除非该条目显式配置了 `agents.list[].runtime.type="acp"`;否则应使用默认子智能体运行时。当一个 OpenClaw 智能体配置了 `runtime.type="acp"` 时,OpenClaw 会使用 `runtime.acp.agent` 作为底层 harness id。
|
||||
对于 `sessions_spawn`,只有在 ACP 已启用、
|
||||
请求方未处于沙箱隔离状态,并且 ACP 运行时后端已加载时,才会公布 `runtime: "acp"`。
|
||||
它面向 ACP harness id,例如 `codex`、`claude`、`droid`、`gemini` 或 `opencode`。不要传入来自 `agents_list` 的普通 OpenClaw 配置智能体 id,除非该条目
|
||||
已显式配置 `agents.list[].runtime.type="acp"`;否则应使用
|
||||
默认的子智能体运行时。当某个 OpenClaw 智能体配置了
|
||||
`runtime.type="acp"` 时,OpenClaw 会将 `runtime.acp.agent` 用作底层
|
||||
harness id。
|
||||
|
||||
## ACP 与子智能体的区别
|
||||
|
||||
当你需要外部 harness 运行时时,请使用 ACP。当 `codex` 插件启用并需要 Codex 对话绑定 / 控制时,请使用原生 Codex 应用服务器。当你需要 OpenClaw 原生委派运行时,请使用子智能体。
|
||||
如果你想使用外部 harness 运行时,请使用 ACP。启用 `codex` 插件时,如需进行 Codex 会话绑定 / 控制,请使用原生 Codex app-server。如果你想要 OpenClaw 原生的委派运行,请使用子智能体。
|
||||
|
||||
| 区域 | ACP 会话 | 子智能体运行 |
|
||||
| ------------- | ------------------------------------- | ---------------------------------- |
|
||||
| 运行时 | ACP 后端插件(例如 acpx) | OpenClaw 原生子智能体运行时 |
|
||||
| 会话键 | `agent:<agentId>:acp:<uuid>` | `agent:<agentId>:subagent:<uuid>` |
|
||||
| 主要命令 | `/acp ...` | `/subagents ...` |
|
||||
| 启动工具 | `sessions_spawn` 配合 `runtime:"acp"` | `sessions_spawn`(默认运行时) |
|
||||
| 会话键 | `agent:<agentId>:acp:<uuid>` | `agent:<agentId>:subagent:<uuid>` |
|
||||
| 主要命令 | `/acp ...` | `/subagents ...` |
|
||||
| 启动工具 | 使用 `runtime:"acp"` 的 `sessions_spawn` | `sessions_spawn`(默认运行时) |
|
||||
|
||||
另请参阅 [Sub-agents](/zh-CN/tools/subagents)。
|
||||
另请参阅[子智能体](/zh-CN/tools/subagents)。
|
||||
|
||||
## ACP 如何运行 Claude Code
|
||||
|
||||
对于通过 ACP 运行的 Claude Code,其堆栈如下:
|
||||
对于通过 ACP 运行 Claude Code,其栈如下:
|
||||
|
||||
1. OpenClaw ACP 会话控制平面
|
||||
2. 内置的 `acpx` 运行时插件
|
||||
3. Claude ACP 适配器
|
||||
3. Claude ACP adapter
|
||||
4. Claude 侧运行时 / 会话机制
|
||||
|
||||
重要区别:
|
||||
|
||||
- ACP Claude 是一种 harness 会话,具有 ACP 控制、会话恢复、后台任务跟踪以及可选的对话 / 线程绑定。
|
||||
- CLI 后端是独立的纯文本本地回退运行时。参见 [CLI Backends](/zh-CN/gateway/cli-backends)。
|
||||
- ACP Claude 是一种 harness 会话,具有 ACP 控制、会话恢复、后台任务跟踪以及可选的会话 / 线程绑定。
|
||||
- CLI 后端是单独的纯文本本地回退运行时。请参阅 [CLI 后端](/zh-CN/gateway/cli-backends)。
|
||||
|
||||
对于运维人员,实际规则是:
|
||||
对运维人员来说,实用规则是:
|
||||
|
||||
- 想要 `/acp spawn`、可绑定会话、运行时控制或持久化 harness 工作:使用 ACP
|
||||
- 想要通过原始 CLI 实现简单的本地文本回退:使用 CLI 后端
|
||||
- 如果你想要 `/acp spawn`、可绑定会话、运行时控制或持久化 harness 工作:使用 ACP
|
||||
- 如果你只想通过原始 CLI 使用简单的本地文本回退:使用 CLI 后端
|
||||
|
||||
## 绑定会话
|
||||
## 已绑定会话
|
||||
|
||||
### 当前对话绑定
|
||||
### 当前会话绑定
|
||||
|
||||
`/acp spawn <harness> --bind here` 会将当前对话固定绑定到已启动的 ACP 会话——不会创建子线程,仍在同一个聊天界面中。OpenClaw 持续负责传输、认证、安全和消息传递;该对话中的后续消息会路由到同一个会话;`/new` 和 `/reset` 会在原地重置该会话;`/acp close` 会移除绑定。
|
||||
`/acp spawn <harness> --bind here` 会将当前会话固定到已启动的 ACP 会话 —— 不创建子线程,使用同一个聊天界面。OpenClaw 继续负责传输、凭证、安全和传递;该会话中的后续消息会路由到同一个会话;`/new` 和 `/reset` 会就地重置该会话;`/acp close` 会移除绑定。
|
||||
|
||||
心智模型:
|
||||
|
||||
- **聊天界面** —— 人们持续交流的地方(Discord 渠道、Telegram 话题、iMessage 聊天)。
|
||||
- **聊天界面** —— 用户持续交流的位置(Discord 频道、Telegram 话题、iMessage 聊天)。
|
||||
- **ACP 会话** —— OpenClaw 路由到的持久化 Codex / Claude / Gemini 运行时状态。
|
||||
- **子线程 / 话题** —— 仅由 `--thread ...` 创建的可选附加消息界面。
|
||||
- **运行时工作区** —— harness 运行的文件系统位置(`cwd`、仓库检出目录、后端工作区)。它独立于聊天界面。
|
||||
- **子线程 / 话题** —— 仅在使用 `--thread ...` 时创建的可选附加消息界面。
|
||||
- **运行时工作区** —— harness 运行所在的文件系统位置(`cwd`、仓库检出目录、后端工作区)。它独立于聊天界面。
|
||||
|
||||
示例:
|
||||
|
||||
- `/codex bind` —— 保持当前聊天,启动或附加原生 Codex 应用服务器,并将未来消息路由到这里。
|
||||
- `/codex model gpt-5.4`、`/codex fast on`、`/codex permissions yolo` —— 在聊天中调整绑定的原生 Codex 线程。
|
||||
- `/codex bind` —— 保留当前聊天,启动或附加原生 Codex app-server,并将未来消息路由到这里。
|
||||
- `/codex model gpt-5.4`、`/codex fast on`、`/codex permissions yolo` —— 在聊天中调整已绑定的原生 Codex 线程。
|
||||
- `/codex stop` 或 `/codex steer focus on the failing tests first` —— 控制当前活跃的原生 Codex 轮次。
|
||||
- `/acp spawn codex --bind here` —— 对 Codex 使用显式 ACP 回退。
|
||||
- `/acp spawn codex --bind here` —— 显式使用 Codex 的 ACP 回退。
|
||||
- `/acp spawn codex --thread auto` —— OpenClaw 可能会创建一个子线程 / 话题并绑定到那里。
|
||||
- `/acp spawn codex --bind here --cwd /workspace/repo` —— 保持当前聊天绑定,但让 Codex 在 `/workspace/repo` 中运行。
|
||||
- `/acp spawn codex --bind here --cwd /workspace/repo` —— 同样绑定当前聊天,但 Codex 在 `/workspace/repo` 中运行。
|
||||
|
||||
说明:
|
||||
|
||||
- `--bind here` 和 `--thread ...` 互斥。
|
||||
- `--bind here` 仅适用于声明支持当前对话绑定的渠道;否则 OpenClaw 会返回明确的不支持消息。绑定会在 Gateway 网关重启后继续保留。
|
||||
- 在 Discord 上,只有当 OpenClaw 需要为 `--thread auto|here` 创建子线程时,才需要 `spawnAcpSessions`——对于 `--bind here` 不需要。
|
||||
- 如果你在不使用 `--cwd` 的情况下启动到另一个 ACP 智能体,OpenClaw 默认会继承**目标智能体的**工作区。缺失的继承路径(`ENOENT` / `ENOTDIR`)会回退到后端默认值;其他访问错误(例如 `EACCES`)会作为启动错误显示。
|
||||
- Gateway 网关管理命令在绑定对话中仍保留本地处理。特别是,即使普通后续文本会路由到绑定的 ACP 会话中,`/acp ...` 命令仍由 OpenClaw 处理;只要该界面启用了命令处理,`/status` 和 `/unfocus` 也始终保留本地处理。
|
||||
- `--bind here` 仅适用于声明支持当前会话绑定的渠道;否则 OpenClaw 会返回清晰的不支持提示。绑定会在 gateway 重启后继续保留。
|
||||
- 在 Discord 上,只有当 OpenClaw 需要为 `--thread auto|here` 创建子线程时,才需要 `spawnAcpSessions` —— 对 `--bind here` 不需要。
|
||||
- 如果你启动到另一个 ACP 智能体且未指定 `--cwd`,OpenClaw 默认会继承**目标智能体的**工作区。缺失的继承路径(`ENOENT` / `ENOTDIR`)会回退到后端默认值;其他访问错误(例如 `EACCES`)会作为启动错误直接显示。
|
||||
- Gateway 网关管理命令在已绑定会话中仍在本地处理。尤其是,`/acp ...` 命令由 OpenClaw 处理,即使普通后续文本会路由到已绑定的 ACP 会话;只要该界面启用了命令处理,`/status` 和 `/unfocus` 也始终在本地处理。
|
||||
|
||||
### 线程绑定会话
|
||||
|
||||
当某个渠道适配器启用了线程绑定时,ACP 会话可以绑定到线程:
|
||||
当渠道适配器启用了线程绑定时,ACP 会话可以绑定到线程:
|
||||
|
||||
- OpenClaw 将一个线程绑定到目标 ACP 会话。
|
||||
- 该线程中的后续消息会路由到绑定的 ACP 会话。
|
||||
- 该线程中的后续消息会路由到已绑定的 ACP 会话。
|
||||
- ACP 输出会回传到同一个线程。
|
||||
- unfocus / close / archive / 空闲超时或最大生命周期过期会移除绑定。
|
||||
- `/acp close`、`/acp cancel`、`/acp status`、`/status` 和 `/unfocus` 是 Gateway 网关命令,而不是发给 ACP harness 的提示。
|
||||
- 失焦 / 关闭 / 归档 / 空闲超时或最大存活时间到期会移除绑定。
|
||||
- `/acp close`、`/acp cancel`、`/acp status`、`/status` 和 `/unfocus` 是
|
||||
Gateway 网关命令,而不是发给 ACP harness 的提示。
|
||||
|
||||
线程绑定支持取决于适配器。如果当前渠道适配器不支持线程绑定,OpenClaw 会返回明确的不支持 / 不可用消息。
|
||||
线程绑定支持取决于具体适配器。如果当前渠道适配器不支持线程绑定,OpenClaw 会返回清晰的不支持 / 不可用提示。
|
||||
|
||||
线程绑定 ACP 所需的功能标志:
|
||||
|
||||
- `acp.enabled=true`
|
||||
- `acp.dispatch.enabled` 默认开启(设置为 `false` 可暂停 ACP 分发)
|
||||
- 渠道适配器的 ACP 线程启动标志已启用(特定于适配器)
|
||||
- 已启用渠道适配器的 ACP 线程启动标志(适配器相关)
|
||||
- Discord:`channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
- Telegram:`channels.telegram.threadBindings.spawnAcpSessions=true`
|
||||
|
||||
### 支持线程的渠道
|
||||
|
||||
- 任何暴露会话 / 线程绑定能力的渠道适配器。
|
||||
- 任何公开会话 / 线程绑定能力的渠道适配器。
|
||||
- 当前内置支持:
|
||||
- Discord 线程 / 渠道
|
||||
- Telegram 话题(群组 / 超级群组中的 forum topic 以及私信话题)
|
||||
- Discord 线程 / 频道
|
||||
- Telegram 话题(群组 / 超级群组中的论坛话题,以及私信话题)
|
||||
- 插件渠道也可以通过同一绑定接口添加支持。
|
||||
|
||||
## 渠道特定设置
|
||||
|
||||
对于非临时工作流,在顶层 `bindings[]` 条目中配置持久化 ACP 绑定。
|
||||
对于非临时性工作流,请在顶层 `bindings[]` 条目中配置持久化 ACP 绑定。
|
||||
|
||||
### 绑定模型
|
||||
|
||||
- `bindings[].type="acp"` 表示一个持久化 ACP 对话绑定。
|
||||
- `bindings[].match` 用于标识目标对话:
|
||||
- Discord 渠道或线程:`match.channel="discord"` + `match.peer.id="<channelOrThreadId>"`
|
||||
- Telegram forum topic:`match.channel="telegram"` + `match.peer.id="<chatId>:topic:<topicId>"`
|
||||
- `bindings[].type="acp"` 标记一个持久化 ACP 会话绑定。
|
||||
- `bindings[].match` 标识目标会话:
|
||||
- Discord 频道或线程:`match.channel="discord"` + `match.peer.id="<channelOrThreadId>"`
|
||||
- Telegram 论坛话题:`match.channel="telegram"` + `match.peer.id="<chatId>:topic:<topicId>"`
|
||||
- BlueBubbles 私信 / 群聊:`match.channel="bluebubbles"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
|
||||
对于稳定的群组绑定,优先使用 `chat_id:*` 或 `chat_identifier:*`。
|
||||
- iMessage 私信 / 群聊:`match.channel="imessage"` + `match.peer.id="<handle|chat_id:*|chat_guid:*|chat_identifier:*>"`
|
||||
对于稳定的群组绑定,优先使用 `chat_id:*`。
|
||||
- `bindings[].agentId` 是所属的 OpenClaw 智能体 id。
|
||||
- `bindings[].agentId` 是拥有该绑定的 OpenClaw 智能体 id。
|
||||
- 可选的 ACP 覆盖项位于 `bindings[].acp` 下:
|
||||
- `mode`(`persistent` 或 `oneshot`)
|
||||
- `label`
|
||||
@ -285,18 +371,18 @@ ACP 绑定会话的覆盖优先级:
|
||||
|
||||
行为:
|
||||
|
||||
- OpenClaw 会在使用前确保已配置的 ACP 会话存在。
|
||||
- 该渠道或话题中的消息会路由到已配置的 ACP 会话。
|
||||
- 在已绑定的对话中,`/new` 和 `/reset` 会原地重置相同的 ACP 会话键。
|
||||
- 临时运行时绑定(例如由线程聚焦流程创建的绑定)在存在时仍会生效。
|
||||
- 对于未显式指定 `cwd` 的跨智能体 ACP 启动,OpenClaw 会从智能体配置中继承目标智能体的工作区。
|
||||
- 缺失的继承工作区路径会回退到后端默认 `cwd`;而非缺失的访问失败则会显示为启动错误。
|
||||
- OpenClaw 会确保配置的 ACP 会话在使用前已存在。
|
||||
- 该频道或话题中的消息会路由到配置的 ACP 会话。
|
||||
- 在已绑定会话中,`/new` 和 `/reset` 会就地重置同一个 ACP 会话键。
|
||||
- 临时运行时绑定(例如由线程聚焦流程创建的绑定)在存在时仍然适用。
|
||||
- 对于未显式指定 `cwd` 的跨智能体 ACP 启动,OpenClaw 会从智能体配置中继承目标智能体工作区。
|
||||
- 缺失的继承工作区路径会回退到后端默认 `cwd`;非缺失类访问失败会作为启动错误直接显示。
|
||||
|
||||
## 启动 ACP 会话(接口)
|
||||
|
||||
### 从 `sessions_spawn` 启动
|
||||
|
||||
使用 `runtime: "acp"` 从智能体轮次或工具调用中启动 ACP 会话。
|
||||
使用 `runtime: "acp"` 可从智能体轮次或工具调用中启动 ACP 会话。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -310,71 +396,86 @@ ACP 绑定会话的覆盖优先级:
|
||||
|
||||
说明:
|
||||
|
||||
- `runtime` 默认为 `subagent`,因此对于 ACP 会话需要显式设置 `runtime: "acp"`。
|
||||
- 如果省略 `agentId`,OpenClaw 会在已配置时使用 `acp.defaultAgent`。
|
||||
- `mode: "session"` 需要 `thread: true` 才能保留持久化绑定对话。
|
||||
- `runtime` 默认为 `subagent`,因此对于 ACP 会话请显式设置 `runtime: "acp"`。
|
||||
- 如果省略 `agentId`,配置后 OpenClaw 会使用 `acp.defaultAgent`。
|
||||
- `mode: "session"` 需要 `thread: true` 才能保留一个持久化的已绑定会话。
|
||||
|
||||
接口细节:
|
||||
|
||||
- `task`(必填):发送到 ACP 会话的初始提示。
|
||||
- `runtime`(ACP 必填):必须为 `"acp"`。
|
||||
- `agentId`(可选):ACP 目标 harness id。如果已设置,则回退到 `acp.defaultAgent`。
|
||||
- `agentId`(可选):ACP 目标 harness id。若已设置,则回退到 `acp.defaultAgent`。
|
||||
- `thread`(可选,默认 `false`):在支持时请求线程绑定流程。
|
||||
- `mode`(可选):`run`(一次性)或 `session`(持久化)。
|
||||
- 默认值是 `run`
|
||||
- `mode`(可选):`run`(单次运行)或 `session`(持久化)。
|
||||
- 默认值为 `run`
|
||||
- 如果 `thread: true` 且省略 `mode`,OpenClaw 可能会根据运行时路径默认采用持久化行为
|
||||
- `mode: "session"` 需要 `thread: true`
|
||||
- `cwd`(可选):请求的运行时工作目录(由后端 / 运行时策略验证)。如果省略,并且已配置目标智能体工作区,则 ACP 启动会继承该工作区;缺失的继承路径会回退到后端默认值,而实际访问错误会被返回。
|
||||
- `cwd`(可选):请求的运行时工作目录(由后端 / 运行时策略校验)。如果省略,则在已配置时,ACP 启动会继承目标智能体工作区;缺失的继承路径会回退到后端默认值,而真实访问错误会直接返回。
|
||||
- `label`(可选):用于会话 / 横幅文本中的面向运维人员的标签。
|
||||
- `resumeSessionId`(可选):恢复现有 ACP 会话,而不是创建新会话。智能体会通过 `session/load` 重放其对话历史。需要 `runtime: "acp"`。
|
||||
- `streamTo`(可选):`"parent"` 会将初始 ACP 运行进度摘要作为系统事件流式返回给请求方会话。
|
||||
- 可用时,接受的响应会包含 `streamLogPath`,指向一个按会话划分的 JSONL 日志(`<sessionId>.acp-stream.jsonl`),你可以 tail 它来查看完整的中继历史。
|
||||
- `runTimeoutSeconds`(可选):在 N 秒后中止 ACP 子轮次。`0` 会让该轮次走 Gateway 网关的无超时路径。相同的值会同时应用到 Gateway 网关运行和 ACP 运行时,以避免卡住 / 配额耗尽的 harness 无限占用父智能体通道。
|
||||
- `model`(可选):对 ACP 子会话的显式模型覆盖。Codex ACP 启动会在 `session/new` 之前,将 OpenClaw Codex 引用(例如 `openai-codex/gpt-5.4`)规范化为 Codex ACP 启动配置;使用斜杠形式(例如 `openai-codex/gpt-5.4/high`)还会设置 Codex ACP 的推理强度。其他 harness 必须声明 ACP `models` 并支持 `session/set_model`;否则 OpenClaw / acpx 会明确失败,而不会静默回退到目标智能体默认值。
|
||||
- `thinking`(可选):对 ACP 子会话的显式思考 / 推理强度。对于 Codex ACP,`minimal` 会映射为低强度,`low` / `medium` / `high` / `xhigh` 会直接映射,而 `off` 会省略推理强度启动覆盖。
|
||||
- `resumeSessionId`(可选):恢复现有 ACP 会话,而不是创建新会话。智能体会通过 `session/load` 重放其会话历史。需要 `runtime: "acp"`。
|
||||
- `streamTo`(可选):`"parent"` 会将初始 ACP 运行的进度摘要作为系统事件流式返回给请求方会话。
|
||||
- 可用时,接受的响应还会包含 `streamLogPath`,指向一个会话级 JSONL 日志(`<sessionId>.acp-stream.jsonl`),你可以对其执行 tail 以查看完整的中继历史。
|
||||
- `runTimeoutSeconds`(可选):在 N 秒后中止 ACP 子轮次。`0` 会让该轮次保持 gateway 的无超时路径。相同的值也会应用到 Gateway 运行和 ACP 运行时,因此卡住或配额耗尽的 harness 不会无限期占用父智能体通道。
|
||||
- `model`(可选):ACP 子会话的显式模型覆盖。Codex ACP 启动会在 `session/new` 之前,将 `openai-codex/gpt-5.4` 这样的 OpenClaw Codex 引用规范化为 Codex ACP 启动配置;像 `openai-codex/gpt-5.4/high` 这样的斜杠形式还会设置 Codex ACP 推理强度。其他 harness 必须声明 ACP `models` 并支持 `session/set_model`;否则 OpenClaw / acpx 会明确失败,而不是静默回退到目标智能体默认值。
|
||||
- `thinking`(可选):ACP 子会话的显式 thinking / 推理强度。对于 Codex ACP,`minimal` 会映射为低强度,`low` / `medium` / `high` / `xhigh` 会直接映射,`off` 则会省略推理强度启动覆盖。
|
||||
|
||||
## 传递模型
|
||||
|
||||
ACP 会话可以是交互式工作区,也可以是父级拥有的后台工作。传递路径取决于这种形态。
|
||||
ACP 会话既可以是交互式工作区,也可以是由父级拥有的后台工作。传递路径取决于其形态。
|
||||
|
||||
### 交互式 ACP 会话
|
||||
|
||||
交互式会话用于在可见的聊天界面中持续对话:
|
||||
交互式会话旨在在一个可见的聊天界面中持续交流:
|
||||
|
||||
- `/acp spawn ... --bind here` 会将当前对话绑定到 ACP 会话。
|
||||
- `/acp spawn ... --thread ...` 会将某个渠道线程 / 话题绑定到 ACP 会话。
|
||||
- 持久化配置的 `bindings[].type="acp"` 会将匹配的对话路由到同一个 ACP 会话。
|
||||
- `/acp spawn ... --bind here` 将当前会话绑定到 ACP 会话。
|
||||
- `/acp spawn ... --thread ...` 将一个渠道线程 / 话题绑定到 ACP 会话。
|
||||
- 持久化配置的 `bindings[].type="acp"` 会将匹配的会话路由到同一个 ACP 会话。
|
||||
|
||||
已绑定对话中的后续消息会直接路由到 ACP 会话,而 ACP 输出会回传到同一个渠道 / 线程 / 话题。
|
||||
已绑定会话中的后续消息会直接路由到 ACP 会话,ACP 输出也会回传到同一个频道 / 线程 / 话题。
|
||||
|
||||
OpenClaw 发送给 harness 的内容:
|
||||
|
||||
- 普通的已绑定后续消息会作为提示文本发送,只有在
|
||||
harness / 后端支持时才会附带附件。
|
||||
- `/acp` 管理命令和本地 Gateway 网关命令会在
|
||||
ACP 分发前被拦截。
|
||||
- 运行时生成的完成事件会按目标进行具体化。OpenClaw
|
||||
智能体会收到 OpenClaw 的内部运行时上下文 envelope;外部 ACP
|
||||
harness 会收到包含子结果和指令的普通提示。原始
|
||||
`<<<BEGIN_OPENCLAW_INTERNAL_CONTEXT>>>` envelope 绝不应发送给
|
||||
外部 harness,也不应作为 ACP 用户转录文本持久化。
|
||||
- ACP 转录条目使用用户可见的触发文本或普通
|
||||
完成提示。内部事件元数据会尽可能以结构化形式保留在 OpenClaw 中,
|
||||
而不会被视为用户撰写的聊天内容。
|
||||
|
||||
### 父级拥有的一次性 ACP 会话
|
||||
|
||||
由另一个智能体运行启动的一次性 ACP 会话属于后台子任务,类似子智能体:
|
||||
由另一个智能体运行启动的一次性 ACP 会话是后台子任务,类似于子智能体:
|
||||
|
||||
- 父级通过 `sessions_spawn({ runtime: "acp", mode: "run" })` 请求工作。
|
||||
- 父级通过 `sessions_spawn({ runtime: "acp", mode: "run" })` 请求执行工作。
|
||||
- 子级在其自己的 ACP harness 会话中运行。
|
||||
- 子级轮次运行在与原生子智能体启动相同的后台通道上,因此慢速 ACP harness 不会阻塞无关的主会话工作。
|
||||
- 完成结果通过任务完成通知路径回报。OpenClaw 会先将内部完成元数据转换为普通 ACP 提示,再发送给外部 harness,因此 harness 不会看到 OpenClaw 专用的运行时上下文标记。
|
||||
- 子级轮次运行在与原生子智能体启动相同的后台通道上,因此缓慢的 ACP harness 不会阻塞无关的主会话工作。
|
||||
- 完成结果会通过任务完成通知路径回传。OpenClaw 会先将内部完成元数据转换为普通 ACP 提示,再发送给外部 harness,因此 harness 看不到 OpenClaw 专用的运行时上下文标记。
|
||||
- 当需要面向用户的回复时,父级会以普通助手语气重写子级结果。
|
||||
|
||||
不要将这条路径视为父子之间的点对点聊天。子级已经有一条返回父级的完成通道。
|
||||
不要将此路径视为父级与子级之间的点对点聊天。子级已经拥有一个回传给父级的完成通道。
|
||||
|
||||
### `sessions_send` 和 A2A 传递
|
||||
|
||||
`sessions_send` 可以在启动后指向另一个会话。对于普通对等会话,OpenClaw 会在注入消息后使用智能体到智能体(A2A)的后续路径:
|
||||
`sessions_send` 可以在启动后以另一个会话为目标。对于普通对等会话,OpenClaw 会在注入消息后使用智能体到智能体(A2A)的后续路径:
|
||||
|
||||
- 等待目标会话的回复
|
||||
- 可选地让请求方和目标进行有限轮数的后续交流
|
||||
- 要求目标生成一条 announce 消息
|
||||
- 将该 announce 发送到可见的渠道或线程
|
||||
- 可选地让请求方和目标方交换有限轮数的后续消息
|
||||
- 要求目标生成一条通知消息
|
||||
- 将该通知传递到可见频道或线程
|
||||
|
||||
对于发送方需要可见后续内容的对等发送场景,这条 A2A 路径是一个回退方案。当某个无关会话可以看到并向 ACP 目标发送消息时,它仍会保持启用,例如在较宽松的 `tools.sessions.visibility` 设置下。
|
||||
该 A2A 路径是对等发送场景中的回退方案,用于发送方需要一个可见的后续回复时。当一个无关会话能够看到并向 ACP 目标发送消息时,它仍保持启用,例如在较宽松的 `tools.sessions.visibility` 设置下。
|
||||
|
||||
只有当请求方是其自己父级拥有的一次性 ACP 子级的父级时,OpenClaw 才会跳过 A2A 后续流程。在这种情况下,如果在任务完成机制之上再运行 A2A,可能会用子级结果唤醒父级,再把父级回复转发回子级,从而形成父子回声循环。对于这种已拥有子级的情况,`sessions_send` 结果会报告 `delivery.status="skipped"`,因为结果已经由完成路径负责处理。
|
||||
只有当请求方是其自身所拥有的一次性 ACP 子任务的父级时,OpenClaw 才会跳过 A2A 后续流程。在这种情况下,在任务完成之上再运行 A2A 可能会用子级结果唤醒父级,再将父级回复转发回子级,并造成父 / 子回声循环。对于这种自有子任务场景,`sessions_send` 结果会报告 `delivery.status="skipped"`,因为完成路径已经负责处理该结果。
|
||||
|
||||
### 恢复现有会话
|
||||
|
||||
使用 `resumeSessionId` 继续之前的 ACP 会话,而不是重新开始。智能体会通过 `session/load` 重放其对话历史,因此它会带着之前的完整上下文继续。
|
||||
使用 `resumeSessionId` 可继续先前的 ACP 会话,而不是重新开始。智能体会通过 `session/load` 重放其会话历史,因此它会带着之前的完整上下文继续。
|
||||
|
||||
```json
|
||||
{
|
||||
@ -385,45 +486,54 @@ ACP 会话可以是交互式工作区,也可以是父级拥有的后台工作
|
||||
}
|
||||
```
|
||||
|
||||
常见使用场景:
|
||||
常见用例:
|
||||
|
||||
- 将一个 Codex 会话从你的笔记本交接到手机——告诉你的智能体从你中断的地方继续
|
||||
- 继续你之前在 CLI 中以交互方式启动、现在想通过智能体以无头方式继续的编码会话
|
||||
- 接着处理因 Gateway 网关重启或空闲超时而中断的工作
|
||||
- 将一个 Codex 会话从你的笔记本交接到手机 —— 告诉你的智能体从你离开的地方继续
|
||||
- 继续一个你最初在 CLI 中以交互方式启动、现在想通过智能体无头运行的编码会话
|
||||
- 继续因 gateway 重启或空闲超时而中断的工作
|
||||
|
||||
说明:
|
||||
|
||||
- `resumeSessionId` 需要 `runtime: "acp"`——如果与子智能体运行时一起使用,会返回错误。
|
||||
- `resumeSessionId` 会恢复上游 ACP 对话历史;`thread` 和 `mode` 仍会正常应用于你正在创建的新 OpenClaw 会话,因此 `mode: "session"` 仍然需要 `thread: true`。
|
||||
- 目标智能体必须支持 `session/load`(Codex 和 Claude Code 支持)。
|
||||
- 如果找不到该会话 id,启动会以明确错误失败——不会静默回退为新会话。
|
||||
- `resumeSessionId` 需要 `runtime: "acp"` —— 如果与子智能体运行时一起使用,会返回错误。
|
||||
- `resumeSessionId` 会恢复上游 ACP 会话历史;`thread` 和 `mode` 仍会正常应用到你正在创建的新 OpenClaw 会话,因此 `mode: "session"` 仍然需要 `thread: true`。
|
||||
- 目标智能体必须支持 `session/load`(Codex 和 Claude Code 都支持)。
|
||||
- 如果找不到该会话 ID,启动会以明确错误失败 —— 不会静默回退到新会话。
|
||||
|
||||
<Accordion title="部署后冒烟测试">
|
||||
<Accordion title="部署后的冒烟测试">
|
||||
|
||||
在 Gateway 网关部署后,运行一次真实的端到端检查,而不是只依赖单元测试:
|
||||
在 gateway 部署后,请运行一次真实的端到端检查,而不是只相信单元测试:
|
||||
|
||||
1. 在目标主机上验证已部署的 Gateway 网关版本和提交。
|
||||
2. 打开一个临时 ACPX 桥接会话,连接到在线智能体。
|
||||
3. 要求该智能体调用 `sessions_spawn`,参数为 `runtime: "acp"`、`agentId: "codex"`、`mode: "run"`,任务内容为 `Reply with exactly LIVE-ACP-SPAWN-OK`。
|
||||
1. 在目标主机上验证已部署的 gateway 版本和提交。
|
||||
2. 打开一个临时的 ACPX 桥接会话,连接到一个在线智能体。
|
||||
3. 要求该智能体调用 `sessions_spawn`,并设置 `runtime: "acp"`、`agentId: "codex"`、`mode: "run"`,以及任务 `Reply with exactly LIVE-ACP-SPAWN-OK`。
|
||||
4. 验证 `accepted=yes`、存在真实的 `childSessionKey`,并且没有校验器错误。
|
||||
5. 清理临时桥接会话。
|
||||
5. 清理该临时桥接会话。
|
||||
|
||||
将检查门槛保持在 `mode: "run"`,并跳过 `streamTo: "parent"`——绑定线程的 `mode: "session"` 和流式中继路径属于单独的、更丰富的集成验证。
|
||||
将门槛保持在 `mode: "run"`,并跳过 `streamTo: "parent"` —— 线程绑定的 `mode: "session"` 和流式中继路径属于单独且更丰富的集成验证。
|
||||
|
||||
</Accordion>
|
||||
|
||||
## 沙箱兼容性
|
||||
|
||||
ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱中。
|
||||
ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱内。
|
||||
|
||||
安全边界:
|
||||
|
||||
- 外部 harness 可以根据其自身 CLI 权限以及所选
|
||||
`cwd` 进行读取 / 写入。
|
||||
- OpenClaw 的沙箱策略不会包裹 ACP harness 执行。
|
||||
- OpenClaw 仍会强制执行 ACP 功能门控、允许的智能体、会话所有权、
|
||||
渠道绑定以及 Gateway 网关传递策略。
|
||||
- 当你需要受沙箱强制约束的 OpenClaw 原生工作时,请使用 `runtime: "subagent"`。
|
||||
|
||||
当前限制:
|
||||
|
||||
- 如果请求方会话处于沙箱隔离中,则 `sessions_spawn({ runtime: "acp" })` 和 `/acp spawn` 都会阻止 ACP 启动。
|
||||
- 如果请求方会话处于沙箱隔离状态,则 ACP 启动会被阻止,无论是 `sessions_spawn({ runtime: "acp" })` 还是 `/acp spawn`。
|
||||
- 错误:`Sandboxed sessions cannot spawn ACP sessions because runtime="acp" runs on the host. Use runtime="subagent" from sandboxed sessions.`
|
||||
- 使用 `runtime: "acp"` 的 `sessions_spawn` 不支持 `sandbox: "require"`。
|
||||
- 带有 `runtime: "acp"` 的 `sessions_spawn` 不支持 `sandbox: "require"`。
|
||||
- 错误:`sessions_spawn sandbox="require" is unsupported for runtime="acp" because ACP sessions run outside the sandbox. Use runtime="subagent" or sandbox="inherit".`
|
||||
|
||||
当你需要强制沙箱执行时,请使用 `runtime: "subagent"`。
|
||||
当你需要受沙箱强制约束的执行时,请使用 `runtime: "subagent"`。
|
||||
|
||||
### 从 `/acp` 命令启动
|
||||
|
||||
@ -444,22 +554,22 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱中。
|
||||
- `--cwd <absolute-path>`
|
||||
- `--label <name>`
|
||||
|
||||
参见 [Slash Commands](/zh-CN/tools/slash-commands)。
|
||||
请参阅[斜杠命令](/zh-CN/tools/slash-commands)。
|
||||
|
||||
## 会话目标解析
|
||||
|
||||
大多数 `/acp` 操作接受一个可选的会话目标(`session-key`、`session-id` 或 `session-label`)。
|
||||
大多数 `/acp` 操作都接受一个可选的会话目标(`session-key`、`session-id` 或 `session-label`)。
|
||||
|
||||
解析顺序:
|
||||
|
||||
1. 显式目标参数(或 `/acp steer` 的 `--session`)
|
||||
- 先尝试 key
|
||||
- 然后尝试 UUID 形状的 session id
|
||||
- 最后尝试 label
|
||||
2. 当前线程绑定(如果此对话 / 线程已绑定到某个 ACP 会话)
|
||||
- 先尝试键
|
||||
- 然后尝试 UUID 形状的会话 id
|
||||
- 最后尝试标签
|
||||
2. 当前线程绑定(如果此会话 / 线程已绑定到 ACP 会话)
|
||||
3. 当前请求方会话回退
|
||||
|
||||
当前对话绑定和线程绑定都会参与第 2 步。
|
||||
当前会话绑定和线程绑定都会参与步骤 2。
|
||||
|
||||
如果无法解析出目标,OpenClaw 会返回明确错误(`Unable to resolve session target: ...`)。
|
||||
|
||||
@ -469,14 +579,14 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱中。
|
||||
|
||||
| 模式 | 行为 |
|
||||
| ------ | ---------------------------------------------------------------------- |
|
||||
| `here` | 在原位置绑定当前活动对话;如果当前没有活动对话则失败。 |
|
||||
| `off` | 不创建当前对话绑定。 |
|
||||
| `here` | 就地绑定当前活动会话;如果当前没有活动会话则失败。 |
|
||||
| `off` | 不创建当前会话绑定。 |
|
||||
|
||||
说明:
|
||||
|
||||
- `--bind here` 是“让这个渠道或聊天由 Codex 提供支持”的最简单运维路径。
|
||||
- `--bind here` 是运维人员实现“让这个频道或聊天由 Codex 提供支持”的最简单路径。
|
||||
- `--bind here` 不会创建子线程。
|
||||
- `--bind here` 仅适用于暴露当前对话绑定支持的渠道。
|
||||
- `--bind here` 仅在公开当前会话绑定支持的渠道上可用。
|
||||
- `--bind` 和 `--thread` 不能在同一个 `/acp spawn` 调用中组合使用。
|
||||
|
||||
## 启动线程模式
|
||||
@ -485,9 +595,9 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱中。
|
||||
|
||||
| 模式 | 行为 |
|
||||
| ------ | --------------------------------------------------------------------------------------------------- |
|
||||
| `auto` | 如果当前处于活动线程中:绑定该线程。在非线程环境下:如支持,则创建 / 绑定一个子线程。 |
|
||||
| `here` | 要求当前必须处于活动线程中;否则失败。 |
|
||||
| `off` | 不进行绑定。会话以未绑定状态启动。 |
|
||||
| `auto` | 在活动线程中:绑定该线程。在线程外:在支持时创建 / 绑定一个子线程。 |
|
||||
| `here` | 要求当前处于活动线程中;如果不在线程中则失败。 |
|
||||
| `off` | 不绑定。会话以未绑定状态启动。 |
|
||||
|
||||
说明:
|
||||
|
||||
@ -495,74 +605,80 @@ ACP 会话当前运行在主机运行时上,而不是 OpenClaw 沙箱中。
|
||||
- 线程绑定启动需要渠道策略支持:
|
||||
- Discord:`channels.discord.threadBindings.spawnAcpSessions=true`
|
||||
- Telegram:`channels.telegram.threadBindings.spawnAcpSessions=true`
|
||||
- 当你想固定当前对话且不创建子线程时,请使用 `--bind here`。
|
||||
- 当你想固定当前会话且不创建子线程时,请使用 `--bind here`。
|
||||
|
||||
## ACP 控制
|
||||
|
||||
| 命令 | 作用 | 示例 |
|
||||
| -------------------- | --------------------------------------------------------- | ------------------------------------------------------------- |
|
||||
| `/acp spawn` | 创建 ACP 会话;可选当前绑定或线程绑定。 | `/acp spawn codex --bind here --cwd /repo` |
|
||||
| `/acp cancel` | 取消目标会话中正在进行的轮次。 | `/acp cancel agent:codex:acp:<uuid>` |
|
||||
| `/acp steer` | 向运行中的会话发送引导指令。 | `/acp steer --session support inbox prioritize failing tests` |
|
||||
| `/acp close` | 关闭会话并解除线程目标绑定。 | `/acp close` |
|
||||
| `/acp status` | 显示后端、模式、状态、运行时选项、能力。 | `/acp status` |
|
||||
| `/acp set-mode` | 为目标会话设置运行时模式。 | `/acp set-mode plan` |
|
||||
| `/acp set` | 通用运行时配置项写入。 | `/acp set model openai/gpt-5.4` |
|
||||
| `/acp cwd` | 设置运行时工作目录覆盖值。 | `/acp cwd /Users/user/Projects/repo` |
|
||||
| `/acp permissions` | 设置审批策略配置文件。 | `/acp permissions strict` |
|
||||
| `/acp timeout` | 设置运行时超时(秒)。 | `/acp timeout 120` |
|
||||
| `/acp model` | 设置运行时模型覆盖值。 | `/acp model anthropic/claude-opus-4-6` |
|
||||
| `/acp reset-options` | 移除会话运行时选项覆盖。 | `/acp reset-options` |
|
||||
| `/acp sessions` | 列出存储中的最近 ACP 会话。 | `/acp sessions` |
|
||||
| `/acp doctor` | 后端健康状态、能力、可执行修复。 | `/acp doctor` |
|
||||
| `/acp install` | 输出确定性的安装和启用步骤。 | `/acp install` |
|
||||
| `/acp spawn` | 创建 ACP 会话;可选当前绑定或线程绑定。 | `/acp spawn codex --bind here --cwd /repo` |
|
||||
| `/acp cancel` | 取消目标会话的进行中轮次。 | `/acp cancel agent:codex:acp:<uuid>` |
|
||||
| `/acp steer` | 向运行中的会话发送引导指令。 | `/acp steer --session support inbox prioritize failing tests` |
|
||||
| `/acp close` | 关闭会话并解绑线程目标。 | `/acp close` |
|
||||
| `/acp status` | 显示后端、模式、状态、运行时选项和能力。 | `/acp status` |
|
||||
| `/acp set-mode` | 为目标会话设置运行时模式。 | `/acp set-mode plan` |
|
||||
| `/acp set` | 通用运行时配置选项写入。 | `/acp set model openai/gpt-5.4` |
|
||||
| `/acp cwd` | 设置运行时工作目录覆盖。 | `/acp cwd /Users/user/Projects/repo` |
|
||||
| `/acp permissions` | 设置审批策略配置。 | `/acp permissions strict` |
|
||||
| `/acp timeout` | 设置运行时超时(秒)。 | `/acp timeout 120` |
|
||||
| `/acp model` | 设置运行时模型覆盖。 | `/acp model anthropic/claude-opus-4-6` |
|
||||
| `/acp reset-options` | 移除会话运行时选项覆盖。 | `/acp reset-options` |
|
||||
| `/acp sessions` | 从存储中列出最近的 ACP 会话。 | `/acp sessions` |
|
||||
| `/acp doctor` | 后端健康状态、能力和可执行修复建议。 | `/acp doctor` |
|
||||
| `/acp install` | 输出确定性的安装和启用步骤。 | `/acp install` |
|
||||
|
||||
`/acp status` 会显示生效的运行时选项,以及运行时级别和后端级别的会话标识符。当后端缺少某项能力时,不支持控制的错误会被明确显示。`/acp sessions` 会为当前绑定会话或请求方会话读取存储;目标令牌(`session-key`、`session-id` 或 `session-label`)会通过 Gateway 网关会话发现进行解析,包括每个智能体自定义的 `session.store` 根目录。
|
||||
`/acp status` 会显示生效的运行时选项,以及运行时级和后端级的会话标识符。当某个后端缺少某项能力时,不支持控制的错误会被清晰地显示出来。`/acp sessions` 会读取当前已绑定会话或请求方会话的存储;目标令牌(`session-key`、`session-id` 或 `session-label`)会通过 gateway 会话发现进行解析,包括自定义的每智能体 `session.store` 根路径。
|
||||
|
||||
## 运行时选项映射
|
||||
|
||||
`/acp` 提供便捷命令和一个通用设置器。
|
||||
`/acp` 提供便捷命令和通用设置器。
|
||||
|
||||
等效操作:
|
||||
|
||||
- `/acp model <id>` 映射到运行时配置键 `model`。对于 Codex ACP,OpenClaw 会将 `openai-codex/<model>` 规范化为适配器模型 id,并将类似 `openai-codex/gpt-5.4/high` 这样的斜杠推理后缀映射为 Codex ACP 的 `reasoning_effort`。对于其他 harness,模型控制取决于适配器是否支持 ACP `models` 和 `session/set_model`。
|
||||
- `/acp set thinking <level>` 映射到运行时配置键 `thinking`。对于 Codex ACP,只要适配器支持,OpenClaw 会发送对应的 `reasoning_effort`。
|
||||
- `/acp model <id>` 映射到运行时配置键 `model`。对于 Codex ACP,OpenClaw 会将 `openai-codex/<model>` 规范化为适配器模型 id,并将诸如 `openai-codex/gpt-5.4/high` 这样的斜杠推理后缀映射为 Codex ACP `reasoning_effort`。对于其他 harness,模型控制取决于适配器是否支持 ACP `models` 和 `session/set_model`。
|
||||
- `/acp set thinking <level>` 映射到运行时配置键 `thinking`。对于 Codex ACP,当适配器支持时,OpenClaw 会发送对应的 `reasoning_effort`。
|
||||
- `/acp permissions <profile>` 映射到运行时配置键 `approval_policy`。
|
||||
- `/acp timeout <seconds>` 映射到运行时配置键 `timeout`。
|
||||
- `/acp cwd <path>` 会直接更新运行时 `cwd` 覆盖值。
|
||||
- `/acp cwd <path>` 直接更新运行时 `cwd` 覆盖值。
|
||||
- `/acp set <key> <value>` 是通用路径。
|
||||
- 特殊情况:`key=cwd` 使用 `cwd` 覆盖路径。
|
||||
- `/acp reset-options` 会清除目标会话的所有运行时覆盖项。
|
||||
- `/acp reset-options` 会清除目标会话的所有运行时覆盖值。
|
||||
|
||||
## acpx harness、插件设置和权限
|
||||
|
||||
有关 acpx harness 配置(Claude Code / Codex / Gemini CLI 别名)、plugin-tools 和 OpenClaw-tools MCP 桥接,以及 ACP 权限模式,请参见
|
||||
有关 acpx harness 配置(Claude Code / Codex / Gemini CLI 别名)、
|
||||
plugin-tools 和 OpenClaw-tools MCP 桥接,以及 ACP 权限模式,请参阅
|
||||
[ACP 智能体 — 设置](/zh-CN/tools/acp-agents-setup)。
|
||||
|
||||
## 故障排除
|
||||
|
||||
| 症状 | 可能原因 | 修复方法 |
|
||||
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `ACP runtime backend is not configured` | 后端插件缺失、已禁用,或被 `plugins.allow` 阻止。 | 安装并启用后端插件;如果设置了 `plugins.allow` 允许列表,请将 `acpx` 包含进去,然后运行 `/acp doctor`。 |
|
||||
| `ACP is disabled by policy (acp.enabled=false)` | ACP 在全局范围内被禁用。 | 设置 `acp.enabled=true`。 |
|
||||
| `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | 已禁用来自普通线程消息的分发。 | 设置 `acp.dispatch.enabled=true`。 |
|
||||
| `ACP agent "<id>" is not allowed by policy` | 智能体不在允许列表中。 | 使用允许的 `agentId`,或更新 `acp.allowedAgents`。 |
|
||||
| `Unable to resolve session target: ...` | key / id / label 令牌错误。 | 运行 `/acp sessions`,复制准确的 key / label,然后重试。 |
|
||||
| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活动且可绑定的对话中使用了 `--bind here`。 | 移动到目标聊天 / 渠道后重试,或使用未绑定的启动方式。 |
|
||||
| `Conversation bindings are unavailable for <channel>.` | 适配器缺少当前对话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`,配置顶层 `bindings[]`,或切换到受支持的渠道。 |
|
||||
| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 移动到目标线程,或使用 `--thread auto` / `off`。 |
|
||||
| `Only <user-id> can rebind this channel/conversation/thread.` | 另一个用户拥有当前活动绑定目标。 | 由所有者重新绑定,或使用其他对话或线程。 |
|
||||
| `Thread bindings are unavailable for <channel>.` | 适配器缺少线程绑定能力。 | 使用 `--thread off`,或切换到受支持的适配器 / 渠道。 |
|
||||
| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时位于主机侧;请求方会话处于沙箱隔离中。 | 在沙箱隔离会话中使用 `runtime="subagent"`,或从非沙箱隔离会话运行 ACP 启动。 |
|
||||
| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 为 ACP 运行时请求了 `sandbox="require"`。 | 若需要强制沙箱隔离,请使用 `runtime="subagent"`;或者从非沙箱隔离会话使用带 `sandbox="inherit"` 的 ACP。 |
|
||||
| `Cannot apply --model ... did not advertise model support` | 目标 harness 未暴露通用 ACP 模型切换支持。 | 使用声明支持 ACP `models` / `session/set_model` 的 harness,使用 Codex ACP 模型引用,或如果该 harness 有自己的启动参数,则直接在 harness 中配置模型。 |
|
||||
| Missing ACP metadata for bound session | 过期 / 已删除的 ACP 会话元数据。 | 使用 `/acp spawn` 重新创建,然后重新绑定 / 聚焦线程。 |
|
||||
| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 在非交互式 ACP 会话中阻止写入 / 执行。 | 将 `plugins.entries.acpx.config.permissionMode` 设置为 `approve-all` 并重启 Gateway 网关。参见[权限配置](/zh-CN/tools/acp-agents-setup#permission-configuration)。 |
|
||||
| ACP session fails early with little output | 权限提示被 `permissionMode` / `nonInteractivePermissions` 阻止。 | 检查 Gateway 网关日志中的 `AcpRuntimeError`。若需完整权限,将 `permissionMode=approve-all`;若需优雅降级,将 `nonInteractivePermissions=deny`。 |
|
||||
| ACP session stalls indefinitely after completing work | harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 进行监控;手动终止陈旧进程。 |
|
||||
| `ACP runtime backend is not configured` | 后端插件缺失、被禁用,或被 `plugins.allow` 阻止。 | 安装并启用后端插件;设置了该 allowlist 时,将 `acpx` 包含在 `plugins.allow` 中;然后运行 `/acp doctor`。 |
|
||||
| `ACP is disabled by policy (acp.enabled=false)` | ACP 已在全局范围被禁用。 | 设置 `acp.enabled=true`。 |
|
||||
| `ACP dispatch is disabled by policy (acp.dispatch.enabled=false)` | 已禁用来自普通线程消息的分发。 | 设置 `acp.dispatch.enabled=true`。 |
|
||||
| `ACP agent "<id>" is not allowed by policy` | 智能体不在 allowlist 中。 | 使用被允许的 `agentId`,或更新 `acp.allowedAgents`。 |
|
||||
| `/acp doctor` reports backend not ready right after startup | 插件依赖探测或自我修复仍在运行。 | 稍等片刻后重新运行 `/acp doctor`;如果仍然不健康,请检查后端安装错误以及插件允许 / 拒绝策略。 |
|
||||
| Harness command not found | 适配器 CLI 未安装,或首次运行的 `npx` 获取失败。 | 在 Gateway 网关主机上安装 / 预热该适配器,或显式配置 acpx 智能体命令。 |
|
||||
| Model-not-found from the harness | 该模型 id 对另一个提供商 / harness 有效,但对这个 ACP 目标无效。 | 使用该 harness 列出的模型、在 harness 中配置该模型,或省略该覆盖值。 |
|
||||
| Vendor auth error from the harness | OpenClaw 正常,但目标 CLI / 提供商尚未登录。 | 在 Gateway 网关主机环境中登录,或提供所需的提供商密钥。 |
|
||||
| `Unable to resolve session target: ...` | 键 / id / 标签令牌错误。 | 运行 `/acp sessions`,复制精确的键 / 标签后重试。 |
|
||||
| `--bind here requires running /acp spawn inside an active ... conversation` | 在没有活动且可绑定的会话中使用了 `--bind here`。 | 切换到目标聊天 / 频道后重试,或使用不绑定的启动方式。 |
|
||||
| `Conversation bindings are unavailable for <channel>.` | 适配器缺少当前会话 ACP 绑定能力。 | 在支持时使用 `/acp spawn ... --thread ...`、配置顶层 `bindings[]`,或切换到受支持的渠道。 |
|
||||
| `--thread here requires running /acp spawn inside an active ... thread` | 在线程上下文之外使用了 `--thread here`。 | 切换到目标线程,或使用 `--thread auto` / `off`。 |
|
||||
| `Only <user-id> can rebind this channel/conversation/thread.` | 当前绑定目标归另一位用户所有。 | 由所有者重新绑定,或使用其他会话或线程。 |
|
||||
| `Thread bindings are unavailable for <channel>.` | 适配器缺少线程绑定能力。 | 使用 `--thread off`,或切换到受支持的适配器 / 渠道。 |
|
||||
| `Sandboxed sessions cannot spawn ACP sessions ...` | ACP 运行时在主机侧运行;请求方会话处于沙箱隔离状态。 | 在沙箱隔离会话中使用 `runtime="subagent"`,或从非沙箱隔离会话启动 ACP。 |
|
||||
| `sessions_spawn sandbox="require" is unsupported for runtime="acp" ...` | 为 ACP 运行时请求了 `sandbox="require"`。 | 对需要沙箱隔离的场景使用 `runtime="subagent"`,或从非沙箱隔离会话以 `sandbox="inherit"` 使用 ACP。 |
|
||||
| `Cannot apply --model ... did not advertise model support` | 目标 harness 未公开通用 ACP 模型切换能力。 | 使用公开 ACP `models` / `session/set_model` 的 harness、使用 Codex ACP 模型引用,或如果该 harness 有自己的启动标志,则直接在其中配置模型。 |
|
||||
| Missing ACP metadata for bound session | ACP 会话元数据已过时 / 被删除。 | 使用 `/acp spawn` 重新创建,然后重新绑定 / 聚焦线程。 |
|
||||
| `AcpRuntimeError: Permission prompt unavailable in non-interactive mode` | `permissionMode` 在非交互 ACP 会话中阻止写入 / 执行。 | 将 `plugins.entries.acpx.config.permissionMode` 设为 `approve-all` 并重启 gateway。请参阅[权限配置](/zh-CN/tools/acp-agents-setup#permission-configuration)。 |
|
||||
| ACP session fails early with little output | 权限提示被 `permissionMode` / `nonInteractivePermissions` 阻止。 | 检查 gateway 日志中的 `AcpRuntimeError`。若要完全开放权限,设置 `permissionMode=approve-all`;若要优雅降级,设置 `nonInteractivePermissions=deny`。 |
|
||||
| ACP session stalls indefinitely after completing work | Harness 进程已结束,但 ACP 会话未报告完成。 | 使用 `ps aux \| grep acpx` 监控;手动杀掉陈旧进程。 |
|
||||
| Harness sees `<<<BEGIN_OPENCLAW_INTERNAL_CONTEXT>>>` | 内部事件 envelope 泄露穿过了 ACP 边界。 | 更新 OpenClaw 并重新运行完成流程;外部 harness 应只接收到普通完成提示。 |
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [Sub-agents](/zh-CN/tools/subagents)
|
||||
- [Multi-agent sandbox tools](/zh-CN/tools/multi-agent-sandbox-tools)
|
||||
- [Agent send](/zh-CN/tools/agent-send)
|
||||
- [子智能体](/zh-CN/tools/subagents)
|
||||
- [多智能体沙箱工具](/zh-CN/tools/multi-agent-sandbox-tools)
|
||||
- [智能体发送](/zh-CN/tools/agent-send)
|
||||
|
||||
@ -2,38 +2,38 @@
|
||||
read_when:
|
||||
- 使用或配置聊天命令
|
||||
- 调试命令路由或权限
|
||||
summary: 斜杠命令:文本与原生、配置和支持的命令
|
||||
summary: 斜杠命令:文本与原生、配置及支持的命令
|
||||
title: 斜杠命令
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T02:05:41Z"
|
||||
generated_at: "2026-04-26T03:01:51Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 4a143508b7d122d0383c61674be5e9f1e91d3561f2e2305d79d54cfb868a1ee4
|
||||
source_hash: cd97db0918e9ca0de77034d9a3e522d8b250ea66b210fc5d16ebfd60d6f73002
|
||||
source_path: tools/slash-commands.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
命令由 Gateway 网关处理。大多数命令必须作为以 `/` 开头的**独立**消息发送。
|
||||
仅主机可用的 bash 聊天命令使用 `! <cmd>`(`/bash <cmd>` 是别名)。
|
||||
仅主机可用的 bash 聊天命令使用 `! <cmd>`(`/bash <cmd>` 是其别名)。
|
||||
|
||||
当某个对话或线程绑定到 ACP 会话时,普通的后续文本
|
||||
会路由到该 ACP harness。Gateway 网关管理命令仍然保留在本地:
|
||||
`/acp ...` 始终会到达 OpenClaw ACP 命令处理器,而 `/status` 和
|
||||
`/unfocus` 在该界面启用命令处理时始终保留本地处理。
|
||||
会路由到该 ACP harness。Gateway 网关管理命令仍然保持本地处理:
|
||||
`/acp ...` 总是会到达 OpenClaw ACP 命令处理器,而 `/status` 和
|
||||
`/unfocus` 在该界面启用命令处理时也始终保持本地处理。
|
||||
|
||||
这里有两个相关系统:
|
||||
|
||||
- **命令**:独立的 `/...` 消息。
|
||||
- **指令**:`/think`、`/fast`、`/verbose`、`/trace`、`/reasoning`、`/elevated`、`/exec`、`/model`、`/queue`。
|
||||
- 在模型看到消息之前,指令会从消息中移除。
|
||||
- 指令会在模型看到消息之前从消息中剥离。
|
||||
- 在普通聊天消息中(不是纯指令消息),它们会被视为“内联提示”,并且**不会**持久化会话设置。
|
||||
- 在纯指令消息中(消息只包含指令),它们会持久化到会话中,并回复确认信息。
|
||||
- 在纯指令消息中(消息只包含指令),它们会持久化到会话,并回复确认信息。
|
||||
- 指令仅对**已授权发送者**生效。如果设置了 `commands.allowFrom`,它就是唯一使用的
|
||||
允许名单;否则,授权来自渠道允许名单/配对以及 `commands.useAccessGroups`。
|
||||
允许列表;否则授权来自渠道允许列表 / 配对以及 `commands.useAccessGroups`。
|
||||
未授权发送者看到的指令会被当作普通文本处理。
|
||||
|
||||
还有一些**内联快捷方式**(仅允许名单内/已授权发送者):`/help`、`/commands`、`/status`、`/whoami`(`/id`)。
|
||||
它们会立即执行,在模型看到消息之前被移除,其余文本则继续走正常流程。
|
||||
还有一些**内联快捷命令**(仅限列入允许列表 / 已授权的发送者):`/help`、`/commands`、`/status`、`/whoami`(`/id`)。
|
||||
它们会立即运行,在模型看到消息之前被剥离,剩余文本继续走正常流程。
|
||||
|
||||
## 配置
|
||||
|
||||
@ -63,48 +63,49 @@ x-i18n:
|
||||
```
|
||||
|
||||
- `commands.text`(默认 `true`)启用在聊天消息中解析 `/...`。
|
||||
- 在没有原生命令的界面上(WhatsApp/WebChat/Signal/iMessage/Google Chat/Microsoft Teams),即使你将其设置为 `false`,文本命令仍然可用。
|
||||
- 在不支持原生命令的界面上(WhatsApp / WebChat / Signal / iMessage / Google Chat / Microsoft Teams),即使你将其设置为 `false`,文本命令仍然可用。
|
||||
- `commands.native`(默认 `"auto"`)注册原生命令。
|
||||
- 自动:对 Discord/Telegram 开启;对 Slack 关闭(直到你添加斜杠命令);对不支持原生功能的提供商忽略。
|
||||
- Auto:对 Discord / Telegram 开启;对 Slack 关闭(直到你添加斜杠命令);对不支持原生命令的提供商会被忽略。
|
||||
- 设置 `channels.discord.commands.native`、`channels.telegram.commands.native` 或 `channels.slack.commands.native` 可按提供商覆盖(布尔值或 `"auto"`)。
|
||||
- `false` 会在启动时清除之前在 Discord/Telegram 上注册的命令。Slack 命令在 Slack 应用中管理,不会被自动移除。
|
||||
- `commands.nativeSkills`(默认 `"auto"`)在支持时原生注册 **Skills** 命令。
|
||||
- 自动:对 Discord/Telegram 开启;对 Slack 关闭(Slack 需要为每个 Skill 单独创建一个斜杠命令)。
|
||||
- `false` 会在启动时清除之前在 Discord / Telegram 上注册的命令。Slack 命令在 Slack 应用中管理,不会自动移除。
|
||||
- `commands.nativeSkills`(默认 `"auto"`)在支持时以原生方式注册 **Skills** 命令。
|
||||
- Auto:对 Discord / Telegram 开启;对 Slack 关闭(Slack 要求为每个 Skill 单独创建一个斜杠命令)。
|
||||
- 设置 `channels.discord.commands.nativeSkills`、`channels.telegram.commands.nativeSkills` 或 `channels.slack.commands.nativeSkills` 可按提供商覆盖(布尔值或 `"auto"`)。
|
||||
- `commands.bash`(默认 `false`)启用 `! <cmd>` 以运行主机 shell 命令(`/bash <cmd>` 是别名;需要 `tools.elevated` 允许名单)。
|
||||
- `commands.bashForegroundMs`(默认 `2000`)控制 bash 在切换到后台模式前等待多久(`0` 表示立即转入后台)。
|
||||
- `commands.config`(默认 `false`)启用 `/config`(读取/写入 `openclaw.json`)。
|
||||
- `commands.mcp`(默认 `false`)启用 `/mcp`(读取/写入 OpenClaw 管理的 `mcp.servers` 下的 MCP 配置)。
|
||||
- `commands.plugins`(默认 `false`)启用 `/plugins`(插件发现/状态,以及安装 + 启用/禁用控制)。
|
||||
- `commands.bash`(默认 `false`)启用 `! <cmd>` 来运行主机 shell 命令(`/bash <cmd>` 是别名;需要 `tools.elevated` 允许列表)。
|
||||
- `commands.bashForegroundMs`(默认 `2000`)控制 bash 在切换到后台模式前等待多长时间(`0` 表示立即转入后台)。
|
||||
- `commands.config`(默认 `false`)启用 `/config`(读取 / 写入 `openclaw.json`)。
|
||||
- `commands.mcp`(默认 `false`)启用 `/mcp`(读取 / 写入 OpenClaw 管理的 `mcp.servers` 下的 MCP 配置)。
|
||||
- `commands.plugins`(默认 `false`)启用 `/plugins`(插件发现 / 状态,以及安装与启用 / 禁用控制)。
|
||||
- `commands.debug`(默认 `false`)启用 `/debug`(仅运行时覆盖)。
|
||||
- `commands.restart`(默认 `true`)启用 `/restart` 以及 Gateway 网关重启工具操作。
|
||||
- `commands.ownerAllowFrom`(可选)为仅限所有者的命令/工具界面设置显式所有者允许名单。这与 `commands.allowFrom` 分开。
|
||||
- 每个渠道的 `channels.<channel>.commands.enforceOwnerForCommands`(可选,默认 `false`)会让仅限所有者的命令在该界面上运行时要求**所有者身份**。当为 `true` 时,发送者必须匹配一个已解析的所有者候选项(例如 `commands.ownerAllowFrom` 中的条目,或提供商原生的所有者元数据),或者在内部消息渠道上拥有内部 `operator.admin` 作用域。渠道 `allowFrom` 中的通配符条目,或空的/无法解析的所有者候选列表,**都不足以**满足要求——仅限所有者的命令会在该渠道上以默认拒绝方式失败。如果你希望仅限所有者的命令只受 `ownerAllowFrom` 和标准命令允许名单控制,请保持此项关闭。
|
||||
- `commands.ownerDisplay` 控制系统提示中所有者 id 的显示方式:`raw` 或 `hash`。
|
||||
- `commands.ownerAllowFrom`(可选)为仅限所有者的命令 / 工具界面设置显式的所有者允许列表。这与 `commands.allowFrom` 分开。
|
||||
- 每个渠道的 `channels.<channel>.commands.enforceOwnerForCommands`(可选,默认 `false`)会让仅限所有者的命令在该界面上要求**所有者身份**才能运行。当为 `true` 时,发送者必须与已解析的所有者候选匹配(例如 `commands.ownerAllowFrom` 中的条目或提供商原生所有者元数据),或者在内部消息渠道上拥有内部 `operator.admin` 作用域。渠道 `allowFrom` 中的通配符条目,或空的 / 未解析的所有者候选列表,**都不足以**满足要求——仅限所有者的命令会在该渠道上以失败关闭方式处理。如果你希望仅限所有者的命令只受 `ownerAllowFrom` 和标准命令允许列表控制,请保持关闭。
|
||||
- `commands.ownerDisplay` 控制所有者 ID 在系统提示中的显示方式:`raw` 或 `hash`。
|
||||
- `commands.ownerDisplaySecret` 可选设置在 `commands.ownerDisplay="hash"` 时使用的 HMAC 密钥。
|
||||
- `commands.allowFrom`(可选)为命令授权设置按提供商划分的允许名单。配置后,它将成为命令和指令的唯一授权来源(渠道允许名单/配对和 `commands.useAccessGroups`
|
||||
会被忽略)。使用 `"*"` 作为全局默认值;提供商特定键会覆盖它。
|
||||
- `commands.useAccessGroups`(默认 `true`)在未设置 `commands.allowFrom` 时,对命令强制执行允许名单/策略。
|
||||
- `commands.allowFrom`(可选)为命令授权设置按提供商划分的允许列表。配置后,它会成为命令和指令的
|
||||
唯一授权来源(渠道允许列表 / 配对以及 `commands.useAccessGroups`
|
||||
会被忽略)。使用 `"*"` 作为全局默认值;提供商专用键会覆盖它。
|
||||
- `commands.useAccessGroups`(默认 `true`)在未设置 `commands.allowFrom` 时,对命令强制执行允许列表 / 策略。
|
||||
|
||||
## 命令列表
|
||||
|
||||
当前的权威来源:
|
||||
当前事实来源:
|
||||
|
||||
- 核心内置命令来自 `src/auto-reply/commands-registry.shared.ts`
|
||||
- 生成的 dock 命令来自 `src/auto-reply/commands-registry.data.ts`
|
||||
- 插件命令来自插件的 `registerCommand()` 调用
|
||||
- 你的 Gateway 网关上的实际可用性仍取决于配置标志、渠道界面以及已安装/已启用的插件
|
||||
- 你的 Gateway 网关上实际可用的命令仍取决于配置标志、渠道界面以及已安装 / 已启用的插件
|
||||
|
||||
### 核心内置命令
|
||||
|
||||
当前可用的内置命令:
|
||||
|
||||
- `/new [model]` 启动一个新会话;`/reset` 是重置别名。
|
||||
- `/reset soft [message]` 保留当前转录内容,丢弃复用的 CLI 后端会话 id,并在原位重新运行启动/系统提示加载。
|
||||
- `/reset soft [message]` 保留当前对话记录,丢弃复用的 CLI 后端会话 ID,并在原位重新运行启动 / 系统提示加载。
|
||||
- `/compact [instructions]` 压缩会话上下文。参见 [/concepts/compaction](/zh-CN/concepts/compaction)。
|
||||
- `/stop` 中止当前运行。
|
||||
- `/session idle <duration|off>` 和 `/session max-age <duration|off>` 管理线程绑定的过期时间。
|
||||
- `/think <level>` 设置思考级别。可选项来自当前活动模型的提供商配置;常见级别有 `off`、`minimal`、`low`、`medium` 和 `high`,也包括如 `xhigh`、`adaptive`、`max` 或仅二元 `on` 这样的自定义级别,但仅在支持时可用。别名:`/thinking`、`/t`。
|
||||
- `/session idle <duration|off>` 和 `/session max-age <duration|off>` 管理线程绑定过期时间。
|
||||
- `/think <level>` 设置 thinking 级别。可选项来自当前模型的提供商配置;常见级别包括 `off`、`minimal`、`low`、`medium` 和 `high`,也包括仅在支持时可用的自定义级别,如 `xhigh`、`adaptive`、`max` 或二元 `on`。别名:`/thinking`、`/t`。
|
||||
- `/verbose on|off|full` 切换详细输出。别名:`/v`。
|
||||
- `/trace on|off` 为当前会话切换插件跟踪输出。
|
||||
- `/fast [status|on|off]` 显示或设置快速模式。
|
||||
@ -112,39 +113,39 @@ x-i18n:
|
||||
- `/elevated [on|off|ask|full]` 切换 elevated 模式。别名:`/elev`。
|
||||
- `/exec host=<auto|sandbox|gateway|node> security=<deny|allowlist|full> ask=<off|on-miss|always> node=<id>` 显示或设置 exec 默认值。
|
||||
- `/model [name|#|status]` 显示或设置模型。
|
||||
- `/models [provider] [page] [limit=<n>|size=<n>|all]` 列出提供商,或列出某个提供商的模型。
|
||||
- `/queue <mode>` 管理队列行为(`steer`、`interrupt`、`followup`、`collect`、`steer-backlog`),以及诸如 `debounce:2s cap:25 drop:summarize` 的选项。
|
||||
- `/models [provider] [page] [limit=<n>|size=<n>|all]` 列出提供商或某个提供商的模型。
|
||||
- `/queue <mode>` 管理队列行为(`steer`、`interrupt`、`followup`、`collect`、`steer-backlog`),以及如 `debounce:2s cap:25 drop:summarize` 之类的选项。
|
||||
- `/help` 显示简短帮助摘要。
|
||||
- `/commands` 显示生成的命令目录。
|
||||
- `/tools [compact|verbose]` 显示当前智能体现在可以使用哪些工具。
|
||||
- `/status` 显示执行/运行时 Status,包括 `Execution`/`Runtime` 标签,以及可用时的提供商使用量/配额。
|
||||
- `/crestodian <request>` 从所有者私信中运行 Crestodian 设置和修复助手。
|
||||
- `/tasks` 列出当前会话的活动/最近后台任务。
|
||||
- `/tools [compact|verbose]` 显示当前智能体此刻可以使用的内容。
|
||||
- `/status` 显示执行 / 运行时状态,包括 `Execution` / `Runtime` 标签,以及可用时的提供商使用量 / 配额。
|
||||
- `/crestodian <request>` 从所有者私信中运行 Crestodian 设置与修复助手。
|
||||
- `/tasks` 列出当前会话的活动 / 最近后台任务。
|
||||
- `/context [list|detail|json]` 说明上下文是如何组装的。
|
||||
- `/export-session [path]` 将当前会话导出为 HTML。别名:`/export`。
|
||||
- `/export-trajectory [path]` 为当前会话导出 JSONL [trajectory bundle](/zh-CN/tools/trajectory)。别名:`/trajectory`。
|
||||
- `/whoami` 显示你的发送者 id。别名:`/id`。
|
||||
- `/whoami` 显示你的发送者 ID。别名:`/id`。
|
||||
- `/skill <name> [input]` 按名称运行一个 Skill。
|
||||
- `/allowlist [list|add|remove] ...` 管理允许名单条目。仅文本命令。
|
||||
- `/allowlist [list|add|remove] ...` 管理允许列表条目。仅文本。
|
||||
- `/approve <id> <decision>` 处理 exec 审批提示。
|
||||
- `/btw <question>` 提出一个旁支问题,而不改变未来的会话上下文。参见 [/tools/btw](/zh-CN/tools/btw)。
|
||||
- `/subagents list|kill|log|info|send|steer|spawn` 管理当前会话的子智能体运行。
|
||||
- `/acp spawn|cancel|steer|close|sessions|status|set-mode|set|cwd|permissions|timeout|model|reset-options|doctor|install|help` 管理 ACP 会话和运行时选项。
|
||||
- `/focus <target>` 将当前 Discord 线程或 Telegram 话题/对话绑定到一个会话目标。
|
||||
- `/focus <target>` 将当前 Discord 线程或 Telegram 话题 / 对话绑定到一个会话目标。
|
||||
- `/unfocus` 移除当前绑定。
|
||||
- `/agents` 列出当前会话中线程绑定的智能体。
|
||||
- `/kill <id|#|all>` 中止一个或所有正在运行的子智能体。
|
||||
- `/kill <id|#|all>` 中止一个或全部正在运行的子智能体。
|
||||
- `/steer <id|#> <message>` 向正在运行的子智能体发送引导。别名:`/tell`。
|
||||
- `/config show|get|set|unset` 读取或写入 `openclaw.json`。仅限所有者。需要 `commands.config: true`。
|
||||
- `/mcp show|get|set|unset` 读取或写入 OpenClaw 管理的 `mcp.servers` 下的 MCP 服务器配置。仅限所有者。需要 `commands.mcp: true`。
|
||||
- `/plugins list|inspect|show|get|install|enable|disable` 检查或修改插件状态。`/plugin` 是别名。写操作仅限所有者。需要 `commands.plugins: true`。
|
||||
- `/debug show|set|unset|reset` 管理仅运行时配置覆盖。仅限所有者。需要 `commands.debug: true`。
|
||||
- `/usage off|tokens|full|cost` 控制每次响应的使用量页脚,或输出本地成本摘要。
|
||||
- `/tts on|off|status|provider|limit|summary|audio|help` 控制 TTS。参见 [/tools/tts](/zh-CN/tools/tts)。
|
||||
- `/debug show|set|unset|reset` 管理仅运行时的配置覆盖。仅限所有者。需要 `commands.debug: true`。
|
||||
- `/usage off|tokens|full|cost` 控制每次响应的使用量页脚,或打印本地成本摘要。
|
||||
- `/tts on|off|status|chat|latest|provider|limit|summary|audio|help` 控制 TTS。参见 [/tools/tts](/zh-CN/tools/tts)。
|
||||
- `/restart` 在启用时重启 OpenClaw。默认:启用;设置 `commands.restart: false` 可禁用。
|
||||
- `/activation mention|always` 设置群组激活模式。
|
||||
- `/send on|off|inherit` 设置发送策略。仅限所有者。
|
||||
- `/bash <command>` 运行主机 shell 命令。仅文本命令。别名:`! <command>`。需要 `commands.bash: true` 以及 `tools.elevated` 允许名单。
|
||||
- `/bash <command>` 运行主机 shell 命令。仅文本。别名:`! <command>`。需要 `commands.bash: true` 以及 `tools.elevated` 允许列表。
|
||||
- `!poll [sessionId]` 检查后台 bash 作业。
|
||||
- `!stop [sessionId]` 停止后台 bash 作业。
|
||||
|
||||
@ -161,13 +162,13 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
内置插件可以添加更多斜杠命令。此仓库中当前内置的命令:
|
||||
|
||||
- `/dreaming [on|off|status|help]` 切换 memory dreaming。参见 [Dreaming](/zh-CN/concepts/dreaming)。
|
||||
- `/pair [qr|status|pending|approve|cleanup|notify]` 管理设备配对/设置流程。参见 [Pairing](/zh-CN/channels/pairing)。
|
||||
- `/dreaming [on|off|status|help]` 切换 Memory Wiki dreaming。参见 [Dreaming](/zh-CN/concepts/dreaming)。
|
||||
- `/pair [qr|status|pending|approve|cleanup|notify]` 管理设备配对 / 设置流程。参见 [Pairing](/zh-CN/channels/pairing)。
|
||||
- `/phone status|arm <camera|screen|writes|all> [duration]|disarm` 临时启用高风险手机节点命令。
|
||||
- `/voice status|list [limit]|set <voiceId|name>` 管理 Talk 语音配置。在 Discord 上,原生命令名称是 `/talkvoice`。
|
||||
- `/card ...` 发送 LINE 富卡片预设。参见 [LINE](/zh-CN/channels/line)。
|
||||
- `/codex status|models|threads|resume|compact|review|account|mcp|skills` 检查并控制内置的 Codex app-server harness。参见 [Codex harness](/zh-CN/plugins/codex-harness)。
|
||||
- 仅 QQ Bot 命令:
|
||||
- 仅限 QQ Bot 的命令:
|
||||
- `/bot-ping`
|
||||
- `/bot-version`
|
||||
- `/bot-help`
|
||||
@ -176,75 +177,75 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
### 动态 Skill 命令
|
||||
|
||||
用户可调用的 Skills 也会作为斜杠命令公开:
|
||||
用户可调用的 Skills 也会暴露为斜杠命令:
|
||||
|
||||
- `/skill <name> [input]` 始终可作为通用入口点使用。
|
||||
- Skills 也可能在 Skill/插件注册时显示为直接命令,例如 `/prose`。
|
||||
- `/skill <name> [input]` 始终可用,作为通用入口点。
|
||||
- 当 Skill / 插件注册它们时,Skills 也可能直接显示为诸如 `/prose` 之类的命令。
|
||||
- 原生 Skill 命令注册由 `commands.nativeSkills` 和 `channels.<provider>.commands.nativeSkills` 控制。
|
||||
|
||||
注意:
|
||||
|
||||
- 命令支持在命令与参数之间使用可选的 `:`(例如 `/think: high`、`/send: on`、`/help:`)。
|
||||
- `/new <model>` 接受模型别名、`provider/model` 或提供商名称(模糊匹配);如果没有匹配,文本会被当作消息正文处理。
|
||||
- 如需查看完整的提供商使用量明细,请使用 `openclaw status --usage`。
|
||||
- 命令在命令与参数之间可选接受一个 `:`(例如 `/think: high`、`/send: on`、`/help:`)。
|
||||
- `/new <model>` 接受模型别名、`provider/model` 或提供商名称(模糊匹配);如果没有匹配,文本会被当作消息正文。
|
||||
- 如需完整的提供商使用量明细,请使用 `openclaw status --usage`。
|
||||
- `/allowlist add|remove` 需要 `commands.config=true`,并遵循渠道的 `configWrites`。
|
||||
- 在多账号渠道中,面向配置目标的 `/allowlist --account <id>` 和 `/config set channels.<provider>.accounts.<id>...` 也会遵循目标账号的 `configWrites`。
|
||||
- `/usage` 控制每次响应的使用量页脚;`/usage cost` 会从 OpenClaw 会话日志中输出本地成本摘要。
|
||||
- `/restart` 默认启用;设置 `commands.restart: false` 可禁用它。
|
||||
- `/plugins install <spec>` 接受与 `openclaw plugins install` 相同的插件规格:本地路径/归档、npm 包或 `clawhub:<pkg>`。
|
||||
- `/plugins enable|disable` 会更新插件配置,并且可能提示重启。
|
||||
- 仅 Discord 原生命令:`/vc join|leave|status` 用于控制语音频道(不提供文本形式)。`join` 需要 guild 和已选择的语音/舞台频道。需要 `channels.discord.voice` 和原生命令。
|
||||
- Discord 线程绑定命令(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`)要求有效启用线程绑定(`session.threadBindings.enabled` 和/或 `channels.discord.threadBindings.enabled`)。
|
||||
- ACP 命令参考和运行时行为: [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
- 在多账号渠道中,面向配置目标的 `/allowlist --account <id>` 和 `/config set channels.<provider>.accounts.<id>...` 也遵循目标账号的 `configWrites`。
|
||||
- `/usage` 控制每次响应的使用量页脚;`/usage cost` 会根据 OpenClaw 会话日志打印本地成本摘要。
|
||||
- `/restart` 默认启用;设置 `commands.restart: false` 可禁用。
|
||||
- `/plugins install <spec>` 接受与 `openclaw plugins install` 相同的插件规格:本地路径 / 压缩包、npm 包,或 `clawhub:<pkg>`。
|
||||
- `/plugins enable|disable` 会更新插件配置,并可能提示重启。
|
||||
- 仅限 Discord 的原生命令:`/vc join|leave|status` 用于控制语音频道(不提供文本形式)。`join` 需要 guild 和已选择的语音 / Stage 频道。需要 `channels.discord.voice` 和原生命令。
|
||||
- Discord 线程绑定命令(`/focus`、`/unfocus`、`/agents`、`/session idle`、`/session max-age`)要求有效线程绑定已启用(`session.threadBindings.enabled` 和 / 或 `channels.discord.threadBindings.enabled`)。
|
||||
- ACP 命令参考与运行时行为:参见 [ACP Agents](/zh-CN/tools/acp-agents)。
|
||||
- `/verbose` 用于调试和额外可见性;在正常使用中请保持**关闭**。
|
||||
- `/trace` 比 `/verbose` 更窄:它只显示插件拥有的 trace/debug 行,并保持普通的详细工具输出关闭。
|
||||
- `/fast on|off` 会持久化一个会话覆盖。使用 Sessions UI 的 `inherit` 选项可清除它,并回退到配置默认值。
|
||||
- `/fast` 是提供商特定的:OpenAI/OpenAI Codex 会在原生 Responses 端点上映射为 `service_tier=priority`,而直接发送到 `api.anthropic.com` 的公共 Anthropic 请求(包括使用 OAuth 身份验证的流量)会映射为 `service_tier=auto` 或 `standard_only`。参见 [OpenAI](/zh-CN/providers/openai) 和 [Anthropic](/zh-CN/providers/anthropic)。
|
||||
- 相关时仍会显示工具失败摘要,但详细的失败文本只会在 `/verbose` 为 `on` 或 `full` 时包含。
|
||||
- `/reasoning`、`/verbose` 和 `/trace` 在群组环境中存在风险:它们可能暴露你原本无意公开的内部推理、工具输出或插件诊断信息。建议保持关闭,尤其是在群聊中。
|
||||
- `/trace` 比 `/verbose` 更窄:它只显示插件拥有的 trace / debug 行,并保持普通详细工具输出关闭。
|
||||
- `/fast on|off` 会持久化一个会话覆盖。使用 Sessions UI 中的 `inherit` 选项可清除它,并回退到配置默认值。
|
||||
- `/fast` 是提供商特定的:OpenAI / OpenAI Codex 会在原生 Responses 端点上将其映射为 `service_tier=priority`,而直接向公开 Anthropic 发出的请求,包括发送到 `api.anthropic.com` 的 OAuth 认证流量,则会将其映射为 `service_tier=auto` 或 `standard_only`。参见 [OpenAI](/zh-CN/providers/openai) 和 [Anthropic](/zh-CN/providers/anthropic)。
|
||||
- 相关时仍会显示工具失败摘要,但详细失败文本仅在 `/verbose` 为 `on` 或 `full` 时包含。
|
||||
- `/reasoning`、`/verbose` 和 `/trace` 在群组场景中有风险:它们可能泄露你原本无意暴露的内部推理、工具输出或插件诊断信息。建议保持关闭,尤其是在群聊中。
|
||||
- `/model` 会立即持久化新的会话模型。
|
||||
- 如果智能体处于空闲状态,下一次运行会立即使用它。
|
||||
- 如果某次运行已经处于活动状态,OpenClaw 会将实时切换标记为待处理,并且只会在一个干净的重试点重启到新模型。
|
||||
- 如果工具活动或回复输出已经开始,这个待处理切换可能会一直排队到之后的某个重试机会,或下一次用户轮次。
|
||||
- 如果某次运行已经处于活动状态,OpenClaw 会将实时切换标记为待处理,并仅在一个干净的重试点重启到新模型。
|
||||
- 如果工具活动或回复输出已经开始,待处理的切换可能会一直排队,直到稍后的重试机会或下一个用户轮次。
|
||||
- 在本地 TUI 中,`/crestodian [request]` 会从普通智能体 TUI 返回到
|
||||
Crestodian。这与消息渠道救援模式是分开的,也不会
|
||||
Crestodian。这与消息渠道救援模式是分开的,并且不会
|
||||
授予远程配置权限。
|
||||
- **快速路径:** 来自允许名单发送者的纯命令消息会被立即处理(绕过队列 + 模型)。
|
||||
- **群组提及门控:** 来自允许名单发送者的纯命令消息会绕过提及要求。
|
||||
- **内联快捷方式(仅允许名单发送者):** 某些命令在嵌入普通消息时也能工作,并会在模型看到剩余文本前被移除。
|
||||
- 示例:`hey /status` 会触发一条状态回复,剩余文本则继续走正常流程。
|
||||
- **快速路径:** 来自允许列表发送者的纯命令消息会被立即处理(绕过队列 + 模型)。
|
||||
- **群组提及门控:** 来自允许列表发送者的纯命令消息会绕过提及要求。
|
||||
- **内联快捷命令(仅限允许列表发送者):** 某些命令也可嵌入普通消息中使用,并会在模型看到剩余文本前被剥离。
|
||||
- 示例:`hey /status` 会触发状态回复,剩余文本继续走正常流程。
|
||||
- 当前包括:`/help`、`/commands`、`/status`、`/whoami`(`/id`)。
|
||||
- 未授权的纯命令消息会被静默忽略,而内联 `/...` 标记会被当作普通文本处理。
|
||||
- **Skill 命令:** `user-invocable` Skills 会公开为斜杠命令。名称会被清洗为 `a-z0-9_`(最多 32 个字符);冲突时会追加数字后缀(例如 `_2`)。
|
||||
- `/skill <name> [input]` 按名称运行一个 Skill(当原生命令限制阻止按 Skill 分别创建命令时,这会很有用)。
|
||||
- 未授权的纯命令消息会被静默忽略,而内联 `/...` 标记会被当作普通文本。
|
||||
- **Skill 命令:** `user-invocable` Skills 会暴露为斜杠命令。名称会被清洗为 `a-z0-9_`(最多 32 个字符);冲突时会添加数字后缀(例如 `_2`)。
|
||||
- `/skill <name> [input]` 按名称运行一个 Skill(当原生命令限制阻止按 Skill 单独建命令时很有用)。
|
||||
- 默认情况下,Skill 命令会作为普通请求转发给模型。
|
||||
- Skills 可选择声明 `command-dispatch: tool`,将命令直接路由到工具(确定性,无模型)。
|
||||
- Skills 也可以选择声明 `command-dispatch: tool`,将命令直接路由给工具(确定性,无模型)。
|
||||
- 示例:`/prose`(OpenProse 插件)——参见 [OpenProse](/zh-CN/prose)。
|
||||
- **原生命令参数:** Discord 对动态选项使用自动补全(当你省略必需参数时,也会使用按钮菜单)。Telegram 和 Slack 会在命令支持可选值且你省略该参数时显示按钮菜单。动态选项会根据目标会话模型解析,因此像 `/think` 级别这样的模型特定选项会遵循该会话的 `/model` 覆盖。
|
||||
- **原生命令参数:** Discord 对动态选项使用自动补全(以及在你省略必需参数时使用按钮菜单)。Telegram 和 Slack 会在命令支持可选项且你省略参数时显示按钮菜单。动态选项会针对目标会话模型解析,因此诸如 `/think` 级别之类的模型特定选项会遵循该会话的 `/model` 覆盖。
|
||||
|
||||
## `/tools`
|
||||
|
||||
`/tools` 回答的是运行时问题,而不是配置问题:**这个智能体现在在
|
||||
这个会话中能使用什么**。
|
||||
此对话中可以使用什么**。
|
||||
|
||||
- 默认的 `/tools` 是紧凑模式,并针对快速浏览进行了优化。
|
||||
- `/tools verbose` 会添加简短描述。
|
||||
- 支持参数的原生命令界面公开相同的模式切换,即 `compact|verbose`。
|
||||
- 结果是按会话划分的,因此更改智能体、渠道、线程、发送者授权或模型,都可能
|
||||
- 默认 `/tools` 为紧凑模式,并针对快速扫描进行了优化。
|
||||
- `/tools verbose` 会添加简短说明。
|
||||
- 支持参数的原生命令界面也会暴露相同的 `compact|verbose` 模式切换。
|
||||
- 结果是会话作用域的,因此更改智能体、渠道、线程、发送者授权或模型都可能
|
||||
改变输出。
|
||||
- `/tools` 包括运行时实际可到达的工具,包括核心工具、已连接的
|
||||
插件工具以及渠道自有工具。
|
||||
- `/tools` 包括在运行时实际可达的工具,包括核心工具、已连接的
|
||||
插件工具和渠道拥有的工具。
|
||||
|
||||
对于配置文件和覆盖项编辑,请使用 Control UI Tools 面板或配置/目录界面,
|
||||
不要把 `/tools` 当作静态目录。
|
||||
如需编辑配置文件和覆盖项,请使用 Control UI 的 Tools 面板或配置 / 目录界面,
|
||||
而不要把 `/tools` 当作静态目录。
|
||||
|
||||
## Usage 界面(各处显示内容)
|
||||
## 使用量界面(各处显示什么)
|
||||
|
||||
- **提供商使用量/配额**(例如:“Claude 剩余 80%”)会在启用使用量跟踪时显示在当前模型提供商的 `/status` 中。OpenClaw 会将提供商窗口统一规范为“剩余百分比”;对于 MiniMax,仅剩余值的百分比字段会在显示前反转,而 `model_remains` 响应会优先使用 chat-model 条目加上带模型标记的套餐标签。
|
||||
- `/status` 中的 **token/cache 行** 可以在实时会话快照内容较少时回退到最新的转录使用量条目。现有的非零实时值仍然优先,而转录回退还可以在已存储总量缺失或较小时恢复活动运行时模型标签以及更偏向提示词的较大总量。
|
||||
- **Execution 与 runtime:** `/status` 会用 `Execution` 报告生效的沙箱路径,并用 `Runtime` 报告实际运行会话的是谁:`OpenClaw Pi Default`、`OpenAI Codex`、某个 CLI 后端或某个 ACP 后端。
|
||||
- **每次响应的 token/成本** 由 `/usage off|tokens|full` 控制(附加到普通回复后)。
|
||||
- `/model status` 关注的是**模型/凭证/端点**,而不是使用量。
|
||||
- **提供商使用量 / 配额**(例如:“Claude 还剩 80%”)会在 `/status` 中针对当前模型提供商显示,前提是已启用使用量跟踪。OpenClaw 会将提供商窗口标准化为“剩余 %”;对于 MiniMax,显示前会先对仅剩余百分比字段取反,而 `model_remains` 响应会优先选择聊天模型条目以及带模型标签的套餐标签。
|
||||
- `/status` 中的**令牌 / 缓存行**在实时会话快照较稀疏时,可以回退到最近一次对话记录使用量条目。现有的非零实时值仍然优先,而对话记录回退还可以在存储总量缺失或较小时,恢复当前活动运行时模型标签以及更大的面向提示的总量。
|
||||
- **Execution 与 Runtime:** `/status` 用 `Execution` 报告实际生效的沙箱路径,用 `Runtime` 报告实际运行会话的是谁:`OpenClaw Pi Default`、`OpenAI Codex`、某个 CLI 后端或某个 ACP 后端。
|
||||
- **每次响应的令牌 / 成本** 由 `/usage off|tokens|full` 控制(附加到普通回复)。
|
||||
- `/model status` 关注的是**模型 / 认证 / 端点**,而不是使用量。
|
||||
|
||||
## 模型选择(`/model`)
|
||||
|
||||
@ -265,12 +266,12 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
- `/model` 和 `/model list` 会显示一个紧凑的编号选择器(模型家族 + 可用提供商)。
|
||||
- 在 Discord 上,`/model` 和 `/models` 会打开一个交互式选择器,其中包含提供商和模型下拉菜单以及 Submit 步骤。
|
||||
- `/model <#>` 会从该选择器中进行选择(并在可能时优先当前提供商)。
|
||||
- `/model status` 会显示详细视图,包括已配置的提供商端点(`baseUrl`)和 API 模式(`api`),如果可用。
|
||||
- `/model <#>` 会从该选择器中进行选择(并在可能时优先使用当前提供商)。
|
||||
- `/model status` 会显示详细视图,包括已配置的提供商端点(`baseUrl`)和 API 模式(`api`),如果可用的话。
|
||||
|
||||
## Debug 覆盖
|
||||
## 调试覆盖
|
||||
|
||||
`/debug` 允许你设置**仅运行时**的配置覆盖(内存中,不写磁盘)。仅限所有者。默认禁用;使用 `commands.debug: true` 启用。
|
||||
`/debug` 允许你设置**仅运行时**配置覆盖(内存中,不写磁盘)。仅限所有者。默认禁用;使用 `commands.debug: true` 启用。
|
||||
|
||||
示例:
|
||||
|
||||
@ -284,12 +285,12 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
注意:
|
||||
|
||||
- 覆盖会立即应用到新的配置读取,但**不会**写入 `openclaw.json`。
|
||||
- 使用 `/debug reset` 清除所有覆盖并返回磁盘上的配置。
|
||||
- 覆盖会立即应用于新的配置读取,但**不会**写入 `openclaw.json`。
|
||||
- 使用 `/debug reset` 清除所有覆盖,并返回磁盘上的配置。
|
||||
|
||||
## 插件 trace 输出
|
||||
## 插件跟踪输出
|
||||
|
||||
`/trace` 允许你切换**会话范围的插件 trace/debug 行**,而无需开启完整详细模式。
|
||||
`/trace` 允许你切换**会话作用域的插件 trace / debug 行**,而无需开启完整详细模式。
|
||||
|
||||
示例:
|
||||
|
||||
@ -301,12 +302,12 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
注意:
|
||||
|
||||
- 不带参数的 `/trace` 会显示当前会话的 trace 状态。
|
||||
- 不带参数的 `/trace` 会显示当前会话 trace 状态。
|
||||
- `/trace on` 会为当前会话启用插件 trace 行。
|
||||
- `/trace off` 会再次禁用它们。
|
||||
- 插件 trace 行可能出现在 `/status` 中,也可能作为普通助手回复后的后续诊断消息出现。
|
||||
- 插件 trace 行可能出现在 `/status` 中,也可能作为普通助手回复之后的后续诊断消息出现。
|
||||
- `/trace` 不能替代 `/debug`;`/debug` 仍用于管理仅运行时配置覆盖。
|
||||
- `/trace` 不能替代 `/verbose`;普通的详细工具/状态输出仍然属于 `/verbose`。
|
||||
- `/trace` 不能替代 `/verbose`;普通详细工具 / 状态输出仍属于 `/verbose`。
|
||||
|
||||
## 配置更新
|
||||
|
||||
@ -324,12 +325,12 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
注意:
|
||||
|
||||
- 写入前会验证配置;无效更改会被拒绝。
|
||||
- `/config` 更新会在重启后继续保留。
|
||||
- 写入前会验证配置;无效变更会被拒绝。
|
||||
- `/config` 更新会在重启后保留。
|
||||
|
||||
## MCP 更新
|
||||
|
||||
`/mcp` 会将 OpenClaw 管理的 MCP 服务器定义写入 `mcp.servers` 下。仅限所有者。默认禁用;使用 `commands.mcp: true` 启用。
|
||||
`/mcp` 会写入 OpenClaw 管理的 `mcp.servers` 下的 MCP 服务器定义。仅限所有者。默认禁用;使用 `commands.mcp: true` 启用。
|
||||
|
||||
示例:
|
||||
|
||||
@ -347,7 +348,7 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
## 插件更新
|
||||
|
||||
`/plugins` 让操作员检查已发现的插件并在配置中切换启用状态。只读流程可以使用 `/plugin` 作为别名。默认禁用;使用 `commands.plugins: true` 启用。
|
||||
`/plugins` 允许操作员检查已发现的插件,并在配置中切换启用状态。只读流程可使用 `/plugin` 作为别名。默认禁用;使用 `commands.plugins: true` 启用。
|
||||
|
||||
示例:
|
||||
|
||||
@ -361,9 +362,9 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
|
||||
注意:
|
||||
|
||||
- `/plugins list` 和 `/plugins show` 会针对当前工作区加上磁盘配置执行真实的插件发现。
|
||||
- `/plugins list` 和 `/plugins show` 会针对当前工作区以及磁盘配置执行真实插件发现。
|
||||
- `/plugins enable|disable` 只更新插件配置;不会安装或卸载插件。
|
||||
- 在启用/禁用变更后,重启 Gateway 网关以应用它们。
|
||||
- 在启用 / 禁用变更后,重启 Gateway 网关以应用它们。
|
||||
|
||||
## 界面说明
|
||||
|
||||
@ -371,35 +372,34 @@ Dock 命令由支持原生命令的渠道插件生成。当前内置集合:
|
||||
- **原生命令** 使用隔离会话:
|
||||
- Discord:`agent:<agentId>:discord:slash:<userId>`
|
||||
- Slack:`agent:<agentId>:slack:slash:<userId>`(前缀可通过 `channels.slack.slashCommand.sessionPrefix` 配置)
|
||||
- Telegram:`telegram:slash:<userId>`(通过 `CommandTargetSessionKey` 定位到聊天会话)
|
||||
- **`/stop`** 以活动聊天会话为目标,因此它可以中止当前运行。
|
||||
- **Slack:** 仍然支持 `channels.slack.slashCommand`,用于单个 `/openclaw` 风格命令。如果你启用了 `commands.native`,则必须为每个内置命令在 Slack 中创建一个斜杠命令(名称与 `/help` 相同)。Slack 的命令参数菜单会以临时 Block Kit 按钮形式提供。
|
||||
- Slack 原生命令例外:请注册 `/agentstatus`(而不是 `/status`),因为 Slack 保留了 `/status`。文本 `/status` 在 Slack 消息中仍然可用。
|
||||
- Telegram:`telegram:slash:<userId>`(通过 `CommandTargetSessionKey` 定向到聊天会话)
|
||||
- **`/stop`** 针对活动聊天会话,因此它可以中止当前运行。
|
||||
- **Slack:** 仍支持 `channels.slack.slashCommand` 用于单个 `/openclaw` 风格命令。如果你启用了 `commands.native`,则必须为每个内置命令创建一个 Slack 斜杠命令(名称与 `/help` 相同)。Slack 的命令参数菜单会以临时 Block Kit 按钮形式发送。
|
||||
- Slack 原生命令例外:注册 `/agentstatus`(而不是 `/status`),因为 Slack 保留了 `/status`。文本 `/status` 在 Slack 消息中仍然可用。
|
||||
|
||||
## BTW 旁支问题
|
||||
|
||||
`/btw` 是关于当前会话的一个快捷**旁支问题**。
|
||||
`/btw` 是一个关于当前会话的快速**旁支问题**。
|
||||
|
||||
与普通聊天不同:
|
||||
|
||||
- 它使用当前会话作为背景上下文,
|
||||
- 它会作为一次单独的**无工具**单次调用运行,
|
||||
- 它以一个独立的**无工具**单次调用运行,
|
||||
- 它不会改变未来的会话上下文,
|
||||
- 它不会写入转录历史,
|
||||
- 它不会写入对话记录历史,
|
||||
- 它会作为实时旁支结果交付,而不是普通助手消息。
|
||||
|
||||
这使得 `/btw` 在你希望主任务继续进行的同时,
|
||||
获得一个临时澄清时非常有用。
|
||||
这使得 `/btw` 在你希望主任务继续进行的同时获得临时澄清时非常有用。
|
||||
|
||||
示例:
|
||||
|
||||
```text
|
||||
/btw what are we doing right now?
|
||||
/btw 我们现在在做什么?
|
||||
```
|
||||
|
||||
完整行为和客户端 UX 细节请参见 [BTW Side Questions](/zh-CN/tools/btw)。
|
||||
|
||||
## 相关内容
|
||||
## 相关
|
||||
|
||||
- [Skills](/zh-CN/tools/skills)
|
||||
- [Skills 配置](/zh-CN/tools/skills-config)
|
||||
|
||||
@ -3,19 +3,19 @@ read_when:
|
||||
- 为回复启用文本转语音
|
||||
- 配置 TTS 提供商或限制
|
||||
- 使用 `/tts` 命令
|
||||
summary: 用于外发回复的文本转语音(TTS)
|
||||
summary: 用于对外回复的文本转语音(TTS)
|
||||
title: 文本转语音
|
||||
x-i18n:
|
||||
generated_at: "2026-04-26T02:32:12Z"
|
||||
generated_at: "2026-04-26T03:02:24Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 710036289a2dc35d70c8c51aecd696e5c90a56903a588c3aaf8e88f40c2851d1
|
||||
source_hash: 18c3792576941f0dab8fede280f837302510ff91df7772809b544d8f00baddbb
|
||||
source_path: tools/tts.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
OpenClaw 可以使用 Azure Speech、ElevenLabs、Google Gemini、Gradium、Inworld、Local CLI、Microsoft、MiniMax、OpenAI、Volcengine、Vydra、xAI 或 Xiaomi MiMo 将外发回复转换为音频。
|
||||
它适用于 OpenClaw 可以发送音频的任何场景。
|
||||
OpenClaw 可以使用 Azure Speech、ElevenLabs、Google Gemini、Gradium、Inworld、Local CLI、Microsoft、MiniMax、OpenAI、Volcengine、Vydra、xAI 或 Xiaomi MiMo 将对外回复转换为音频。
|
||||
只要 OpenClaw 能发送音频的地方,它都可以工作。
|
||||
|
||||
## 支持的服务
|
||||
|
||||
@ -35,59 +35,65 @@ OpenClaw 可以使用 Azure Speech、ElevenLabs、Google Gemini、Gradium、Inwo
|
||||
|
||||
### Microsoft 语音说明
|
||||
|
||||
内置的 Microsoft 语音提供商当前通过 `node-edge-tts` 库使用 Microsoft Edge 的在线神经网络 TTS 服务。它是托管服务(不是本地服务),使用 Microsoft 的端点,并且不需要 API 密钥。
|
||||
`node-edge-tts` 提供语音配置选项和输出格式,但并非所有选项都受该服务支持。使用 `edge` 的旧版配置和指令输入仍然有效,并会被规范化为 `microsoft`。
|
||||
当前内置的 Microsoft 语音提供商通过 `node-edge-tts` 库使用 Microsoft Edge 的在线神经 TTS 服务。它是托管服务(不是本地服务),使用 Microsoft 端点,并且不需要 API 密钥。
|
||||
`node-edge-tts` 提供语音配置选项和输出格式,但并非所有选项都受到该服务支持。使用 `edge` 的旧版配置和指令输入仍然可用,并会标准化为 `microsoft`。
|
||||
|
||||
由于这一路径是没有公开 SLA 或配额说明的公共 Web 服务,应将其视为尽力而为。如果你需要有保障的限制和支持,请使用 OpenAI 或 ElevenLabs。
|
||||
由于这一路径是公共 Web 服务,且没有公开的 SLA 或配额,请将其视为尽力而为的服务。如果你需要有保障的限制和支持,请使用 OpenAI 或 ElevenLabs。
|
||||
|
||||
## 可选键
|
||||
## 可选密钥
|
||||
|
||||
如果你想使用 Azure Speech、ElevenLabs、Google Gemini、Gradium、Inworld、MiniMax、OpenAI、Volcengine、Vydra、xAI 或 Xiaomi MiMo:
|
||||
如果你要使用 Azure Speech、ElevenLabs、Google Gemini、Gradium、Inworld、MiniMax、OpenAI、Volcengine、Vydra、xAI 或 Xiaomi MiMo:
|
||||
|
||||
- `AZURE_SPEECH_KEY` 加上 `AZURE_SPEECH_REGION`(也接受 `AZURE_SPEECH_API_KEY`、`SPEECH_KEY` 和 `SPEECH_REGION`)
|
||||
- `AZURE_SPEECH_KEY` 加上 `AZURE_SPEECH_REGION`(也接受
|
||||
`AZURE_SPEECH_API_KEY`、`SPEECH_KEY` 和 `SPEECH_REGION`)
|
||||
- `ELEVENLABS_API_KEY`(或 `XI_API_KEY`)
|
||||
- `GEMINI_API_KEY`(或 `GOOGLE_API_KEY`)
|
||||
- `GRADIUM_API_KEY`
|
||||
- `INWORLD_API_KEY`
|
||||
- `MINIMAX_API_KEY`;MiniMax TTS 还接受通过 `MINIMAX_OAUTH_TOKEN`、`MINIMAX_CODE_PLAN_KEY` 或 `MINIMAX_CODING_API_KEY` 进行的 Token Plan 认证
|
||||
- `MINIMAX_API_KEY`;MiniMax TTS 也接受 Token Plan 认证,通过
|
||||
`MINIMAX_OAUTH_TOKEN`、`MINIMAX_CODE_PLAN_KEY` 或
|
||||
`MINIMAX_CODING_API_KEY`
|
||||
- `OPENAI_API_KEY`
|
||||
- `VOLCENGINE_TTS_API_KEY`(或 `BYTEPLUS_SEED_SPEECH_API_KEY`);旧版 AppID/token 认证也接受 `VOLCENGINE_TTS_APPID` 和 `VOLCENGINE_TTS_TOKEN`
|
||||
- `VOLCENGINE_TTS_API_KEY`(或 `BYTEPLUS_SEED_SPEECH_API_KEY`);
|
||||
旧版 AppID/token 认证也接受 `VOLCENGINE_TTS_APPID` 和
|
||||
`VOLCENGINE_TTS_TOKEN`
|
||||
- `VYDRA_API_KEY`
|
||||
- `XAI_API_KEY`
|
||||
- `XIAOMI_API_KEY`
|
||||
|
||||
Local CLI 和 Microsoft 语音 **不** 需要 API 密钥。
|
||||
Local CLI 和 Microsoft 语音**不**需要 API 密钥。
|
||||
|
||||
如果配置了多个提供商,则会先使用所选提供商,其他提供商作为回退选项。
|
||||
自动摘要使用已配置的 `summaryModel`(或 `agents.defaults.model.primary`),因此如果你启用了摘要,对应的提供商也必须完成认证。
|
||||
如果配置了多个提供商,将优先使用所选提供商,其他提供商作为回退选项。
|
||||
自动摘要使用已配置的 `summaryModel`(或 `agents.defaults.model.primary`),因此如果你启用了摘要,也必须为该提供商完成认证。
|
||||
|
||||
## 服务链接
|
||||
|
||||
- [OpenAI 文本转语音指南](https://platform.openai.com/docs/guides/text-to-speech)
|
||||
- [OpenAI 音频 API 参考](https://platform.openai.com/docs/api-reference/audio)
|
||||
- [Azure Speech REST 文本转语音](https://learn.microsoft.com/azure/ai-services/speech-service/rest-text-to-speech)
|
||||
- [OpenAI Text-to-Speech guide](https://platform.openai.com/docs/guides/text-to-speech)
|
||||
- [OpenAI Audio API reference](https://platform.openai.com/docs/api-reference/audio)
|
||||
- [Azure Speech REST text-to-speech](https://learn.microsoft.com/azure/ai-services/speech-service/rest-text-to-speech)
|
||||
- [Azure Speech provider](/zh-CN/providers/azure-speech)
|
||||
- [ElevenLabs 文本转语音](https://elevenlabs.io/docs/api-reference/text-to-speech)
|
||||
- [ElevenLabs 认证](https://elevenlabs.io/docs/api-reference/authentication)
|
||||
- [ElevenLabs Text to Speech](https://elevenlabs.io/docs/api-reference/text-to-speech)
|
||||
- [ElevenLabs Authentication](https://elevenlabs.io/docs/api-reference/authentication)
|
||||
- [Gradium](/zh-CN/providers/gradium)
|
||||
- [Inworld TTS API](https://docs.inworld.ai/tts/tts)
|
||||
- [MiniMax T2A v2 API](https://platform.minimaxi.com/document/T2A%20V2)
|
||||
- [Volcengine TTS HTTP API](/zh-CN/providers/volcengine#text-to-speech)
|
||||
- [Xiaomi MiMo 语音合成](/zh-CN/providers/xiaomi#text-to-speech)
|
||||
- [Xiaomi MiMo speech synthesis](/zh-CN/providers/xiaomi#text-to-speech)
|
||||
- [node-edge-tts](https://github.com/SchneeHertz/node-edge-tts)
|
||||
- [Microsoft Speech 输出格式](https://learn.microsoft.com/azure/ai-services/speech-service/rest-text-to-speech#audio-outputs)
|
||||
- [xAI 文本转语音](https://docs.x.ai/developers/rest-api-reference/inference/voice#text-to-speech-rest)
|
||||
- [Microsoft Speech output formats](https://learn.microsoft.com/azure/ai-services/speech-service/rest-text-to-speech#audio-outputs)
|
||||
- [xAI Text to Speech](https://docs.x.ai/developers/rest-api-reference/inference/voice#text-to-speech-rest)
|
||||
|
||||
## 默认启用吗?
|
||||
|
||||
不会。自动 TTS 默认是**关闭**的。在配置中使用 `messages.tts.auto` 启用,或在本地使用 `/tts on` 启用。
|
||||
不是。自动 TTS 默认**关闭**。可在配置中通过
|
||||
`messages.tts.auto` 启用,或在本地通过 `/tts on` 启用。
|
||||
|
||||
当未设置 `messages.tts.provider` 时,OpenClaw 会按照注册表自动选择顺序挑选第一个已配置的语音提供商。
|
||||
当未设置 `messages.tts.provider` 时,OpenClaw 会按注册表自动选择顺序选取第一个已配置的语音提供商。
|
||||
|
||||
## 配置
|
||||
|
||||
TTS 配置位于 `openclaw.json` 的 `messages.tts` 下。
|
||||
完整 schema 见 [Gateway 网关配置](/zh-CN/gateway/configuration)。
|
||||
完整 schema 请参阅 [Gateway 网关配置](/zh-CN/gateway/configuration)。
|
||||
|
||||
### 最小配置(启用 + 提供商)
|
||||
|
||||
@ -102,10 +108,9 @@ TTS 配置位于 `openclaw.json` 的 `messages.tts` 下。
|
||||
}
|
||||
```
|
||||
|
||||
### 按智能体覆盖语音设置
|
||||
### 每个智能体的语音覆盖
|
||||
|
||||
当某个智能体需要使用不同的提供商、语音、模型、风格或自动 TTS 模式时,请使用 `agents.list[].tts`。
|
||||
智能体块会在 `messages.tts` 之上进行深度合并,因此提供商凭证可以保留在全局提供商配置中。
|
||||
当某个智能体需要使用不同的提供商、voice、model、style 或自动 TTS 模式时,请使用 `agents.list[].tts`。该智能体块会在 `messages.tts` 之上执行深度合并,因此提供商凭证可以保留在全局提供商配置中。
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -138,14 +143,15 @@ TTS 配置位于 `openclaw.json` 的 `messages.tts` 下。
|
||||
}
|
||||
```
|
||||
|
||||
自动回复、`/tts audio`、`/tts status` 和 `tts` 智能体工具的优先级如下:
|
||||
自动回复、`/tts audio`、`/tts status` 和 `tts`
|
||||
智能体工具的优先级为:
|
||||
|
||||
1. `messages.tts`
|
||||
2. 当前激活的 `agents.list[].tts`
|
||||
2. 当前活动的 `agents.list[].tts`
|
||||
3. 此主机的本地 `/tts` 偏好设置
|
||||
4. 启用模型覆盖时的内联 `[[tts:...]]` 指令
|
||||
|
||||
### OpenAI 主提供商 + ElevenLabs 回退
|
||||
### OpenAI 作为主提供商,ElevenLabs 作为回退
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -186,7 +192,7 @@ TTS 配置位于 `openclaw.json` 的 `messages.tts` 下。
|
||||
}
|
||||
```
|
||||
|
||||
### Azure Speech 主提供商
|
||||
### Azure Speech 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -196,8 +202,8 @@ TTS 配置位于 `openclaw.json` 的 `messages.tts` 下。
|
||||
provider: "azure-speech",
|
||||
providers: {
|
||||
"azure-speech": {
|
||||
// apiKey 会回退到 AZURE_SPEECH_KEY。
|
||||
// region 会回退到 AZURE_SPEECH_REGION。
|
||||
// apiKey 默认回退到 AZURE_SPEECH_KEY。
|
||||
// region 默认回退到 AZURE_SPEECH_REGION。
|
||||
voice: "en-US-JennyNeural",
|
||||
lang: "en-US",
|
||||
outputFormat: "audio-24khz-48kbitrate-mono-mp3",
|
||||
@ -209,12 +215,13 @@ TTS 配置位于 `openclaw.json` 的 `messages.tts` 下。
|
||||
}
|
||||
```
|
||||
|
||||
Azure Speech 使用的是 Speech 资源密钥,而不是 Azure OpenAI 密钥。解析顺序为 `messages.tts.providers.azure-speech.apiKey` ->
|
||||
Azure Speech 使用 Speech 资源密钥,而不是 Azure OpenAI 密钥。解析顺序为 `messages.tts.providers.azure-speech.apiKey` ->
|
||||
`AZURE_SPEECH_KEY` -> `AZURE_SPEECH_API_KEY` -> `SPEECH_KEY`,区域则为
|
||||
`messages.tts.providers.azure-speech.region` -> `AZURE_SPEECH_REGION` ->
|
||||
`SPEECH_REGION`。新配置应使用 `azure-speech`;`azure` 可作为提供商别名接受。
|
||||
`SPEECH_REGION`。新配置应使用 `azure-speech`;`azure`
|
||||
可作为提供商别名使用。
|
||||
|
||||
### Microsoft 主提供商(无 API 密钥)
|
||||
### Microsoft 作为主提供商(无 API 密钥)
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -237,7 +244,7 @@ Azure Speech 使用的是 Speech 资源密钥,而不是 Azure OpenAI 密钥。
|
||||
}
|
||||
```
|
||||
|
||||
### MiniMax 主提供商
|
||||
### MiniMax 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -261,9 +268,13 @@ Azure Speech 使用的是 Speech 资源密钥,而不是 Azure OpenAI 密钥。
|
||||
}
|
||||
```
|
||||
|
||||
MiniMax TTS 认证解析顺序是 `messages.tts.providers.minimax.apiKey`,然后是已存储的 `minimax-portal` OAuth/token 配置文件,再然后是 Token Plan 环境变量键(`MINIMAX_OAUTH_TOKEN`、`MINIMAX_CODE_PLAN_KEY`、`MINIMAX_CODING_API_KEY`),最后是 `MINIMAX_API_KEY`。当未显式设置 TTS `baseUrl` 时,OpenClaw 可以复用已配置的 `minimax-portal` OAuth 主机用于 Token Plan 语音。
|
||||
MiniMax TTS 的认证解析顺序是 `messages.tts.providers.minimax.apiKey`,然后是已存储的 `minimax-portal` OAuth/token 配置文件,再然后是 Token Plan 环境变量密钥
|
||||
(`MINIMAX_OAUTH_TOKEN`、`MINIMAX_CODE_PLAN_KEY`、
|
||||
`MINIMAX_CODING_API_KEY`),最后才是 `MINIMAX_API_KEY`。当未显式设置 TTS
|
||||
`baseUrl` 时,OpenClaw 可以复用已配置的 `minimax-portal` OAuth
|
||||
主机用于 Token Plan 语音。
|
||||
|
||||
### Google Gemini 主提供商
|
||||
### Google Gemini 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -283,10 +294,11 @@ MiniMax TTS 认证解析顺序是 `messages.tts.providers.minimax.apiKey`,然
|
||||
}
|
||||
```
|
||||
|
||||
Google Gemini TTS 使用 Gemini API 密钥路径。限制为 Gemini API 的 Google Cloud Console API 密钥在这里也可用,并且它与内置 Google 图像生成提供商所使用的密钥类型相同。解析顺序为 `messages.tts.providers.google.apiKey` -> `models.providers.google.apiKey` ->
|
||||
Google Gemini TTS 使用 Gemini API 密钥路径。这里可以使用限制为 Gemini API 的 Google Cloud Console API 密钥,这也是内置 Google 图像生成提供商所使用的同类密钥。解析顺序为
|
||||
`messages.tts.providers.google.apiKey` -> `models.providers.google.apiKey` ->
|
||||
`GEMINI_API_KEY` -> `GOOGLE_API_KEY`。
|
||||
|
||||
### Inworld 主提供商
|
||||
### Inworld 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -308,9 +320,10 @@ Google Gemini TTS 使用 Gemini API 密钥路径。限制为 Gemini API 的 Goog
|
||||
}
|
||||
```
|
||||
|
||||
`apiKey` 的值必须是从 Inworld 控制台(Workspace > API Keys)逐字复制的 Base64 编码凭证字符串。该提供商会将其作为 `Authorization: Basic <apiKey>` 发送,而不会进行任何额外编码,因此不要传入原始 bearer token,也不要自行再次进行 Base64 编码。该密钥会回退到 `INWORLD_API_KEY` 环境变量。完整设置见 [Inworld provider](/zh-CN/providers/inworld)。
|
||||
`apiKey` 的值必须是从 Inworld 控制台原样复制的 Base64 编码凭证字符串(Workspace > API Keys)。该提供商会直接将其作为 `Authorization: Basic <apiKey>` 发送,不会再做任何额外编码,因此不要传入原始 bearer token,也不要自行再次进行 Base64 编码。该密钥默认回退到 `INWORLD_API_KEY` 环境变量。完整设置请参阅
|
||||
[Inworld provider](/zh-CN/providers/inworld)。
|
||||
|
||||
### Volcengine 主提供商
|
||||
### Volcengine 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -331,10 +344,12 @@ Google Gemini TTS 使用 Gemini API 密钥路径。限制为 Gemini API 的 Goog
|
||||
}
|
||||
```
|
||||
|
||||
Volcengine TTS 使用的是来自 Speech Console 的 BytePlus Seed Speech API 密钥,而不是 Doubao 模型提供商使用的 OpenAI 兼容 `VOLCANO_ENGINE_API_KEY`。解析顺序为 `messages.tts.providers.volcengine.apiKey` ->
|
||||
`VOLCENGINE_TTS_API_KEY` -> `BYTEPLUS_SEED_SPEECH_API_KEY`。旧版 AppID/token 认证仍可通过 `messages.tts.providers.volcengine.appId` / `token` 或 `VOLCENGINE_TTS_APPID` / `VOLCENGINE_TTS_TOKEN` 使用。语音便笺目标会请求提供商原生的 `ogg_opus`;普通音频文件目标会请求 `mp3`。
|
||||
Volcengine TTS 使用来自 Speech Console 的 BytePlus Seed Speech API 密钥,而不是 Doubao 模型提供商使用的 OpenAI 兼容 `VOLCANO_ENGINE_API_KEY`。解析顺序为 `messages.tts.providers.volcengine.apiKey` ->
|
||||
`VOLCENGINE_TTS_API_KEY` -> `BYTEPLUS_SEED_SPEECH_API_KEY`。旧版 AppID/token
|
||||
认证仍然可通过 `messages.tts.providers.volcengine.appId` / `token` 或
|
||||
`VOLCENGINE_TTS_APPID` / `VOLCENGINE_TTS_TOKEN` 使用。语音便笺目标会请求提供商原生的 `ogg_opus`;普通音频文件目标会请求 `mp3`。
|
||||
|
||||
### xAI 主提供商
|
||||
### xAI 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -356,9 +371,9 @@ Volcengine TTS 使用的是来自 Speech Console 的 BytePlus Seed Speech API
|
||||
}
|
||||
```
|
||||
|
||||
xAI TTS 与内置 Grok 模型提供商使用相同的 `XAI_API_KEY` 路径。解析顺序为 `messages.tts.providers.xai.apiKey` -> `XAI_API_KEY`。当前可用的实时语音为 `ara`、`eve`、`leo`、`rex`、`sal` 和 `una`;默认值为 `eve`。`language` 接受 BCP-47 标签或 `auto`。
|
||||
xAI TTS 与内置的 Grok 模型提供商使用相同的 `XAI_API_KEY` 路径。解析顺序为 `messages.tts.providers.xai.apiKey` -> `XAI_API_KEY`。当前可用的 live voices 为 `ara`、`eve`、`leo`、`rex`、`sal` 和 `una`;默认值为 `eve`。`language` 接受 BCP-47 标签或 `auto`。
|
||||
|
||||
### Xiaomi MiMo 主提供商
|
||||
### Xiaomi MiMo 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -373,7 +388,7 @@ xAI TTS 与内置 Grok 模型提供商使用相同的 `XAI_API_KEY` 路径。解
|
||||
model: "mimo-v2.5-tts",
|
||||
voice: "mimo_default",
|
||||
format: "mp3",
|
||||
style: "Bright, natural, conversational tone.",
|
||||
style: "明亮、自然、对话式的语气。",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -381,9 +396,9 @@ xAI TTS 与内置 Grok 模型提供商使用相同的 `XAI_API_KEY` 路径。解
|
||||
}
|
||||
```
|
||||
|
||||
Xiaomi MiMo TTS 与内置 Xiaomi 模型提供商使用相同的 `XIAOMI_API_KEY` 路径。语音提供商 ID 是 `xiaomi`;`mimo` 也可作为别名。目标文本会作为 assistant message 发送,以匹配 Xiaomi 的 TTS 协议。可选的 `style` 会作为 user instruction 发送,不会被朗读出来。
|
||||
Xiaomi MiMo TTS 与内置 Xiaomi 模型提供商使用相同的 `XIAOMI_API_KEY` 路径。语音提供商 id 为 `xiaomi`;`mimo` 也可作为别名使用。目标文本会作为 assistant message 发送,这与 Xiaomi 的 TTS 协议保持一致。可选的 `style` 会作为 user instruction 发送,不会被朗读出来。
|
||||
|
||||
### OpenRouter 主提供商
|
||||
### OpenRouter 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -408,7 +423,7 @@ OpenRouter TTS 与内置 OpenRouter 模型提供商使用相同的 `OPENROUTER_A
|
||||
`messages.tts.providers.openrouter.apiKey` ->
|
||||
`models.providers.openrouter.apiKey` -> `OPENROUTER_API_KEY`。
|
||||
|
||||
### Local CLI 主提供商
|
||||
### Local CLI 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -429,9 +444,11 @@ OpenRouter TTS 与内置 OpenRouter 模型提供商使用相同的 `OPENROUTER_A
|
||||
}
|
||||
```
|
||||
|
||||
Local CLI TTS 会在 Gateway 网关主机上运行已配置的命令。`args` 中的 `{{Text}}`、`{{OutputPath}}`、`{{OutputDir}}` 和 `{{OutputBase}}` 占位符会被展开;如果不存在 `{{Text}}` 占位符,OpenClaw 会将要朗读的文本写入 stdin。`outputFormat` 接受 `mp3`、`opus` 或 `wav`。语音便笺目标会被转码为 Ogg/Opus,电话输出会通过 `ffmpeg` 转码为原始 16 kHz 单声道 PCM。旧版提供商别名 `cli` 仍然可用,但新配置应使用 `tts-local-cli`。
|
||||
Local CLI TTS 会在 Gateway 网关主机上运行已配置的命令。`{{Text}}`、
|
||||
`{{OutputPath}}`、`{{OutputDir}}` 和 `{{OutputBase}}` 占位符会在 `args` 中展开;如果不存在 `{{Text}}` 占位符,OpenClaw 会将要朗读的文本写入 stdin。`outputFormat` 接受 `mp3`、`opus` 或 `wav`。
|
||||
语音便笺目标会转码为 Ogg/Opus,电话输出会通过 `ffmpeg` 转码为原始 16 kHz 单声道 PCM。旧版提供商别名 `cli` 仍然可用,但新配置应使用 `tts-local-cli`。
|
||||
|
||||
### Gradium 主提供商
|
||||
### Gradium 作为主提供商
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -467,7 +484,7 @@ Local CLI TTS 会在 Gateway 网关主机上运行已配置的命令。`args`
|
||||
}
|
||||
```
|
||||
|
||||
### 自定义限制 + prefs 路径
|
||||
### 自定义限制 + 偏好设置路径
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -517,129 +534,139 @@ Local CLI TTS 会在 Gateway 网关主机上运行已配置的命令。`args`
|
||||
- `auto`:自动 TTS 模式(`off`、`always`、`inbound`、`tagged`)。
|
||||
- `inbound` 仅在收到入站语音消息后发送音频。
|
||||
- `tagged` 仅在回复包含 `[[tts:key=value]]` 指令或 `[[tts:text]]...[[/tts:text]]` 块时发送音频。
|
||||
- `enabled`:旧版开关(`doctor` 会将其迁移为 `auto`)。
|
||||
- `enabled`:旧版开关(Doctor 会将其迁移到 `auto`)。
|
||||
- `mode`:`"final"`(默认)或 `"all"`(包含工具/分块回复)。
|
||||
- `provider`:语音提供商 ID,例如 `"elevenlabs"`、`"google"`、`"gradium"`、`"inworld"`、`"microsoft"`、`"minimax"`、`"openai"`、`"volcengine"`、`"vydra"`、`"xai"` 或 `"xiaomi"`(回退会自动处理)。
|
||||
- `provider`:语音提供商 id,例如 `"elevenlabs"`、`"google"`、`"gradium"`、`"inworld"`、`"microsoft"`、`"minimax"`、`"openai"`、`"volcengine"`、`"vydra"`、`"xai"` 或 `"xiaomi"`(回退会自动处理)。
|
||||
- 如果 `provider` **未设置**,OpenClaw 会按注册表自动选择顺序使用第一个已配置的语音提供商。
|
||||
- 旧版 `provider: "edge"` 配置可由 `openclaw doctor --fix` 修复,并重写为 `provider: "microsoft"`。
|
||||
- 旧版 `provider: "edge"` 配置可通过 `openclaw doctor --fix` 修复,并重写为 `provider: "microsoft"`。
|
||||
- `summaryModel`:用于自动摘要的可选低成本模型;默认为 `agents.defaults.model.primary`。
|
||||
- 接受 `provider/model` 或已配置的模型别名。
|
||||
- `modelOverrides`:允许模型输出 TTS 指令(默认开启)。
|
||||
- `allowProvider` 默认为 `false`(切换提供商需要显式启用)。
|
||||
- `providers.<id>`:由提供商拥有的设置,按语音提供商 ID 键控。
|
||||
- 旧版直接提供商块(`messages.tts.openai`、`messages.tts.elevenlabs`、`messages.tts.microsoft`、`messages.tts.edge`)可由 `openclaw doctor --fix` 修复;已提交的配置应使用 `messages.tts.providers.<id>`。
|
||||
- 旧版 `messages.tts.providers.edge` 也会由 `openclaw doctor --fix` 修复;已提交的配置应使用 `messages.tts.providers.microsoft`。
|
||||
- `maxTextLength`:TTS 输入的硬性上限(字符数)。超出时,`/tts audio` 会失败。
|
||||
- `providers.<id>`:由提供商拥有的设置,按语音提供商 id 分组。
|
||||
- 旧版直接提供商块(`messages.tts.openai`、`messages.tts.elevenlabs`、`messages.tts.microsoft`、`messages.tts.edge`)可通过 `openclaw doctor --fix` 修复;提交的配置应使用 `messages.tts.providers.<id>`。
|
||||
- 旧版 `messages.tts.providers.edge` 也可通过 `openclaw doctor --fix` 修复;提交的配置应使用 `messages.tts.providers.microsoft`。
|
||||
- `maxTextLength`:TTS 输入的硬限制(字符数)。如果超出,`/tts audio` 会失败。
|
||||
- `timeoutMs`:请求超时(毫秒)。
|
||||
- `prefsPath`:覆盖本地 prefs JSON 路径(提供商/限制/摘要)。
|
||||
- `apiKey` 值会回退到环境变量(`AZURE_SPEECH_KEY`/`AZURE_SPEECH_API_KEY`/`SPEECH_KEY`、`ELEVENLABS_API_KEY`/`XI_API_KEY`、`GEMINI_API_KEY`/`GOOGLE_API_KEY`、`GRADIUM_API_KEY`、`INWORLD_API_KEY`、`MINIMAX_API_KEY`、`OPENAI_API_KEY`、`VYDRA_API_KEY`、`XAI_API_KEY`、`XIAOMI_API_KEY`)。Volcengine 改用 `appId`/`token`。
|
||||
- `providers.azure-speech.apiKey`:Azure Speech 资源密钥(环境变量:`AZURE_SPEECH_KEY`、`AZURE_SPEECH_API_KEY` 或 `SPEECH_KEY`)。
|
||||
- `providers.azure-speech.region`:Azure Speech 区域,例如 `eastus`(环境变量:`AZURE_SPEECH_REGION` 或 `SPEECH_REGION`)。
|
||||
- `prefsPath`:覆盖本地偏好设置 JSON 路径(提供商/限制/摘要)。
|
||||
- `apiKey` 值会回退到环境变量(`AZURE_SPEECH_KEY`/`AZURE_SPEECH_API_KEY`/`SPEECH_KEY`、`ELEVENLABS_API_KEY`/`XI_API_KEY`、`GEMINI_API_KEY`/`GOOGLE_API_KEY`、`GRADIUM_API_KEY`、`INWORLD_API_KEY`、`MINIMAX_API_KEY`、`OPENAI_API_KEY`、`VYDRA_API_KEY`、`XAI_API_KEY`、`XIAOMI_API_KEY`)。Volcengine 则使用 `appId`/`token`。
|
||||
- `providers.azure-speech.apiKey`:Azure Speech 资源密钥(环境变量:
|
||||
`AZURE_SPEECH_KEY`、`AZURE_SPEECH_API_KEY` 或 `SPEECH_KEY`)。
|
||||
- `providers.azure-speech.region`:Azure Speech 区域,例如 `eastus`(环境变量:
|
||||
`AZURE_SPEECH_REGION` 或 `SPEECH_REGION`)。
|
||||
- `providers.azure-speech.endpoint` / `providers.azure-speech.baseUrl`:可选的 Azure Speech endpoint/base URL 覆盖。
|
||||
- `providers.azure-speech.voice`:Azure 语音 ShortName(默认 `en-US-JennyNeural`)。
|
||||
- `providers.azure-speech.voice`:Azure voice ShortName(默认
|
||||
`en-US-JennyNeural`)。
|
||||
- `providers.azure-speech.lang`:SSML 语言代码(默认 `en-US`)。
|
||||
- `providers.azure-speech.outputFormat`:用于标准音频输出的 Azure `X-Microsoft-OutputFormat`(默认 `audio-24khz-48kbitrate-mono-mp3`)。
|
||||
- `providers.azure-speech.voiceNoteOutputFormat`:用于语音便笺输出的 Azure `X-Microsoft-OutputFormat`(默认 `ogg-24khz-16bit-mono-opus`)。
|
||||
- `providers.azure-speech.outputFormat`:标准音频输出的 Azure `X-Microsoft-OutputFormat`(默认 `audio-24khz-48kbitrate-mono-mp3`)。
|
||||
- `providers.azure-speech.voiceNoteOutputFormat`:语音便笺输出的 Azure
|
||||
`X-Microsoft-OutputFormat`(默认
|
||||
`ogg-24khz-16bit-mono-opus`)。
|
||||
- `providers.elevenlabs.baseUrl`:覆盖 ElevenLabs API base URL。
|
||||
- `providers.openai.baseUrl`:覆盖 OpenAI TTS endpoint。
|
||||
- 解析顺序:`messages.tts.providers.openai.baseUrl` -> `OPENAI_TTS_BASE_URL` -> `https://api.openai.com/v1`
|
||||
- 非默认值会被视为与 OpenAI 兼容的 TTS endpoint,因此接受自定义模型名和语音名。
|
||||
- 非默认值会被视为 OpenAI 兼容 TTS endpoint,因此接受自定义 model 和 voice 名称。
|
||||
- `providers.elevenlabs.voiceSettings`:
|
||||
- `stability`、`similarityBoost`、`style`:`0..1`
|
||||
- `useSpeakerBoost`:`true|false`
|
||||
- `speed`:`0.5..2.0`(1.0 = 正常)
|
||||
- `providers.elevenlabs.applyTextNormalization`:`auto|on|off`
|
||||
- `providers.elevenlabs.languageCode`:2 字母 ISO 639-1 代码(例如 `en`、`de`)
|
||||
- `providers.elevenlabs.seed`:整数 `0..4294967295`(尽力保证确定性)
|
||||
- `providers.elevenlabs.languageCode`:2 位 ISO 639-1 代码(例如 `en`、`de`)
|
||||
- `providers.elevenlabs.seed`:整数 `0..4294967295`(尽力提供确定性)
|
||||
- `providers.minimax.baseUrl`:覆盖 MiniMax API base URL(默认 `https://api.minimax.io`,环境变量:`MINIMAX_API_HOST`)。
|
||||
- `providers.minimax.model`:TTS 模型(默认 `speech-2.8-hd`,环境变量:`MINIMAX_TTS_MODEL`)。
|
||||
- `providers.minimax.voiceId`:语音标识符(默认 `English_expressive_narrator`,环境变量:`MINIMAX_TTS_VOICE_ID`)。
|
||||
- `providers.minimax.voiceId`:voice 标识符(默认 `English_expressive_narrator`,环境变量:`MINIMAX_TTS_VOICE_ID`)。
|
||||
- `providers.minimax.speed`:播放速度 `0.5..2.0`(默认 1.0)。
|
||||
- `providers.minimax.vol`:音量 `(0, 10]`(默认 1.0;必须大于 0)。
|
||||
- `providers.minimax.pitch`:整数音高偏移 `-12..12`(默认 0)。调用 MiniMax T2A 之前会截断小数值,因为该 API 会拒绝非整数音高值。
|
||||
- `providers.minimax.pitch`:整数音高偏移 `-12..12`(默认 0)。小数值在调用 MiniMax T2A 前会被截断,因为该 API 拒绝非整数音高值。
|
||||
- `providers.tts-local-cli.command`:用于 CLI TTS 的本地可执行文件或命令字符串。
|
||||
- `providers.tts-local-cli.args`:命令参数;支持 `{{Text}}`、`{{OutputPath}}`、`{{OutputDir}}` 和 `{{OutputBase}}` 占位符。
|
||||
- `providers.tts-local-cli.outputFormat`:预期的 CLI 输出格式(`mp3`、`opus` 或 `wav`;音频附件默认使用 `mp3`)。
|
||||
- `providers.tts-local-cli.timeoutMs`:命令超时时间(毫秒,默认 `120000`)。
|
||||
- `providers.tts-local-cli.outputFormat`:预期的 CLI 输出格式(`mp3`、`opus` 或 `wav`;音频附件默认 `mp3`)。
|
||||
- `providers.tts-local-cli.timeoutMs`:命令超时(毫秒,默认 `120000`)。
|
||||
- `providers.tts-local-cli.cwd`:可选的命令工作目录。
|
||||
- `providers.tts-local-cli.env`:命令的可选字符串环境变量覆盖。
|
||||
- `providers.tts-local-cli.env`:可选的命令字符串环境变量覆盖。
|
||||
- `providers.inworld.baseUrl`:覆盖 Inworld API base URL(默认 `https://api.inworld.ai`)。
|
||||
- `providers.inworld.voiceId`:Inworld 语音标识符(默认 `Sarah`)。
|
||||
- `providers.inworld.voiceId`:Inworld voice 标识符(默认 `Sarah`)。
|
||||
- `providers.inworld.modelId`:Inworld TTS 模型(默认 `inworld-tts-1.5-max`;也支持 `inworld-tts-1.5-mini`、`inworld-tts-1-max`、`inworld-tts-1`)。
|
||||
- `providers.inworld.temperature`:采样温度 `0..2`(可选)。
|
||||
- `providers.inworld.temperature`:采样 temperature `0..2`(可选)。
|
||||
- `providers.google.model`:Gemini TTS 模型(默认 `gemini-3.1-flash-tts-preview`)。
|
||||
- `providers.google.voiceName`:Gemini 预设语音名称(默认 `Kore`;也接受 `voice`)。
|
||||
- `providers.google.audioProfile`:在要朗读的文本前附加的自然语言风格提示。
|
||||
- `providers.google.speakerName`:当你的 TTS 提示使用命名说话人时,在要朗读文本前附加的可选说话人标签。
|
||||
- `providers.google.baseUrl`:覆盖 Gemini API base URL。只接受 `https://generativelanguage.googleapis.com`。
|
||||
- 如果省略 `messages.tts.providers.google.apiKey`,TTS 可以在回退到环境变量之前复用 `models.providers.google.apiKey`。
|
||||
- `providers.google.voiceName`:Gemini 预置 voice 名称(默认 `Kore`;也接受 `voice`)。
|
||||
- `providers.google.audioProfile`:会在朗读文本前附加的自然语言风格提示。
|
||||
- `providers.google.speakerName`:当你的 TTS 提示使用命名说话人时,会在朗读文本前附加的可选说话人标签。
|
||||
- `providers.google.baseUrl`:覆盖 Gemini API base URL。仅接受 `https://generativelanguage.googleapis.com`。
|
||||
- 如果省略 `messages.tts.providers.google.apiKey`,TTS 可以在环境变量回退前复用 `models.providers.google.apiKey`。
|
||||
- `providers.gradium.baseUrl`:覆盖 Gradium API base URL(默认 `https://api.gradium.ai`)。
|
||||
- `providers.gradium.voiceId`:Gradium 语音标识符(默认 Emma,`YTpq7expH9539ERJ`)。
|
||||
- `providers.volcengine.apiKey`:BytePlus Seed Speech API 密钥(环境变量:`VOLCENGINE_TTS_API_KEY` 或 `BYTEPLUS_SEED_SPEECH_API_KEY`)。
|
||||
- `providers.volcengine.resourceId`:BytePlus Seed Speech 资源 ID(默认 `seed-tts-1.0`,环境变量:`VOLCENGINE_TTS_RESOURCE_ID`;当你的 BytePlus 项目具有 TTS 2.0 权限时,请使用 `seed-tts-2.0`)。
|
||||
- `providers.volcengine.appKey`:BytePlus Seed Speech app key 请求头(默认 `aGjiRDfUWi`,环境变量:`VOLCENGINE_TTS_APP_KEY`)。
|
||||
- `providers.volcengine.baseUrl`:覆盖 Seed Speech TTS HTTP endpoint(环境变量:`VOLCENGINE_TTS_BASE_URL`)。
|
||||
- `providers.gradium.voiceId`:Gradium voice 标识符(默认 Emma,`YTpq7expH9539ERJ`)。
|
||||
- `providers.volcengine.apiKey`:BytePlus Seed Speech API 密钥(环境变量:
|
||||
`VOLCENGINE_TTS_API_KEY` 或 `BYTEPLUS_SEED_SPEECH_API_KEY`)。
|
||||
- `providers.volcengine.resourceId`:BytePlus Seed Speech 资源 id(默认
|
||||
`seed-tts-1.0`,环境变量:`VOLCENGINE_TTS_RESOURCE_ID`;当你的 BytePlus 项目拥有 TTS 2.0 权限时,请使用 `seed-tts-2.0`)。
|
||||
- `providers.volcengine.appKey`:BytePlus Seed Speech app key header(默认
|
||||
`aGjiRDfUWi`,环境变量:`VOLCENGINE_TTS_APP_KEY`)。
|
||||
- `providers.volcengine.baseUrl`:覆盖 Seed Speech TTS HTTP endpoint
|
||||
(环境变量:`VOLCENGINE_TTS_BASE_URL`)。
|
||||
- `providers.volcengine.appId`:旧版 Volcengine Speech Console application id(环境变量:`VOLCENGINE_TTS_APPID`)。
|
||||
- `providers.volcengine.token`:旧版 Volcengine Speech Console access token(环境变量:`VOLCENGINE_TTS_TOKEN`)。
|
||||
- `providers.volcengine.cluster`:旧版 Volcengine TTS 集群(默认 `volcano_tts`,环境变量:`VOLCENGINE_TTS_CLUSTER`)。
|
||||
- `providers.volcengine.voice`:语音类型(默认 `en_female_anna_mars_bigtts`,环境变量:`VOLCENGINE_TTS_VOICE`)。
|
||||
- `providers.volcengine.cluster`:旧版 Volcengine TTS cluster(默认 `volcano_tts`,环境变量:`VOLCENGINE_TTS_CLUSTER`)。
|
||||
- `providers.volcengine.voice`:voice 类型(默认 `en_female_anna_mars_bigtts`,环境变量:`VOLCENGINE_TTS_VOICE`)。
|
||||
- `providers.volcengine.speedRatio`:提供商原生速度比率。
|
||||
- `providers.volcengine.emotion`:提供商原生情感标签。
|
||||
- `providers.xai.apiKey`:xAI TTS API 密钥(环境变量:`XAI_API_KEY`)。
|
||||
- `providers.xai.baseUrl`:覆盖 xAI TTS base URL(默认 `https://api.x.ai/v1`,环境变量:`XAI_BASE_URL`)。
|
||||
- `providers.xai.voiceId`:xAI 语音 ID(默认 `eve`;当前可用实时语音:`ara`、`eve`、`leo`、`rex`、`sal`、`una`)。
|
||||
- `providers.xai.voiceId`:xAI voice id(默认 `eve`;当前 live voices:`ara`、`eve`、`leo`、`rex`、`sal`、`una`)。
|
||||
- `providers.xai.language`:BCP-47 语言代码或 `auto`(默认 `en`)。
|
||||
- `providers.xai.responseFormat`:`mp3`、`wav`、`pcm`、`mulaw` 或 `alaw`(默认 `mp3`)。
|
||||
- `providers.xai.speed`:提供商原生速度覆盖。
|
||||
- `providers.xiaomi.apiKey`:Xiaomi MiMo API 密钥(环境变量:`XIAOMI_API_KEY`)。
|
||||
- `providers.xiaomi.baseUrl`:覆盖 Xiaomi MiMo API base URL(默认 `https://api.xiaomimimo.com/v1`,环境变量:`XIAOMI_BASE_URL`)。
|
||||
- `providers.xiaomi.model`:TTS 模型(默认 `mimo-v2.5-tts`,环境变量:`XIAOMI_TTS_MODEL`;也支持 `mimo-v2-tts`)。
|
||||
- `providers.xiaomi.voice`:MiMo 语音 ID(默认 `mimo_default`,环境变量:`XIAOMI_TTS_VOICE`)。
|
||||
- `providers.xiaomi.voice`:MiMo voice id(默认 `mimo_default`,环境变量:`XIAOMI_TTS_VOICE`)。
|
||||
- `providers.xiaomi.format`:`mp3` 或 `wav`(默认 `mp3`,环境变量:`XIAOMI_TTS_FORMAT`)。
|
||||
- `providers.xiaomi.style`:可选的自然语言风格指令,会作为 user message 发送;不会被朗读。
|
||||
- `providers.xiaomi.style`:可选的自然语言风格指令,会作为 user message 发送;不会被朗读出来。
|
||||
- `providers.openrouter.apiKey`:OpenRouter API 密钥(环境变量:`OPENROUTER_API_KEY`;可复用 `models.providers.openrouter.apiKey`)。
|
||||
- `providers.openrouter.baseUrl`:覆盖 OpenRouter TTS base URL(默认 `https://openrouter.ai/api/v1`;旧版 `https://openrouter.ai/v1` 会被规范化)。
|
||||
- `providers.openrouter.model`:OpenRouter TTS 模型 ID(默认 `hexgrad/kokoro-82m`;也接受 `modelId`)。
|
||||
- `providers.openrouter.voice`:提供商特定的语音 ID(默认 `af_alloy`;也接受 `voiceId`)。
|
||||
- `providers.openrouter.baseUrl`:覆盖 OpenRouter TTS base URL(默认 `https://openrouter.ai/api/v1`;旧版 `https://openrouter.ai/v1` 会被标准化)。
|
||||
- `providers.openrouter.model`:OpenRouter TTS model id(默认 `hexgrad/kokoro-82m`;也接受 `modelId`)。
|
||||
- `providers.openrouter.voice`:提供商特定的 voice id(默认 `af_alloy`;也接受 `voiceId`)。
|
||||
- `providers.openrouter.responseFormat`:`mp3` 或 `pcm`(默认 `mp3`)。
|
||||
- `providers.openrouter.speed`:提供商原生速度覆盖。
|
||||
- `providers.microsoft.enabled`:允许使用 Microsoft 语音(默认 `true`;无 API 密钥)。
|
||||
- `providers.microsoft.voice`:Microsoft 神经网络语音名称(例如 `en-US-MichelleNeural`)。
|
||||
- `providers.microsoft.enabled`:允许使用 Microsoft 语音(默认 `true`;无需 API 密钥)。
|
||||
- `providers.microsoft.voice`:Microsoft 神经 voice 名称(例如 `en-US-MichelleNeural`)。
|
||||
- `providers.microsoft.lang`:语言代码(例如 `en-US`)。
|
||||
- `providers.microsoft.outputFormat`:Microsoft 输出格式(例如 `audio-24khz-48kbitrate-mono-mp3`)。
|
||||
- 有效值见 Microsoft Speech 输出格式;并非所有格式都受内置的 Edge 后端传输支持。
|
||||
- 有效值请参阅 Microsoft Speech 输出格式;并非所有格式都受内置的 Edge 支持传输方式支持。
|
||||
- `providers.microsoft.rate` / `providers.microsoft.pitch` / `providers.microsoft.volume`:百分比字符串(例如 `+10%`、`-5%`)。
|
||||
- `providers.microsoft.saveSubtitles`:在音频文件旁写入 JSON 字幕。
|
||||
- `providers.microsoft.proxy`:Microsoft 语音请求使用的代理 URL。
|
||||
- `providers.microsoft.proxy`:Microsoft 语音请求的代理 URL。
|
||||
- `providers.microsoft.timeoutMs`:请求超时覆盖(毫秒)。
|
||||
- `edge.*`:同一组 Microsoft 设置的旧版别名。运行 `openclaw doctor --fix` 可将持久化配置重写为 `providers.microsoft`。
|
||||
- `edge.*`:相同 Microsoft 设置的旧版别名。运行
|
||||
`openclaw doctor --fix` 将持久化配置重写为 `providers.microsoft`。
|
||||
|
||||
## 模型驱动的覆盖(默认开启)
|
||||
|
||||
默认情况下,模型**可以**为单条回复输出 TTS 指令。
|
||||
当 `messages.tts.auto` 为 `tagged` 时,必须有这些指令才会触发音频。
|
||||
当 `messages.tts.auto` 为 `tagged` 时,必须使用这些指令才能触发音频。
|
||||
|
||||
启用后,模型可以输出 `[[tts:...]]` 指令来为单条回复覆盖语音设置,还可以附带一个可选的 `[[tts:text]]...[[/tts:text]]` 块,用于提供表达性标签(笑声、歌唱提示等),这些内容只应出现在音频中。
|
||||
启用后,模型可以输出 `[[tts:...]]` 指令以覆盖单条回复的 voice,还可以附带可选的 `[[tts:text]]...[[/tts:text]]` 块,用于提供只应出现在音频中的表现性标签(笑声、歌唱提示等)。
|
||||
|
||||
除非设置 `modelOverrides.allowProvider: true`,否则 `provider=...` 指令会被忽略。
|
||||
|
||||
示例回复负载:
|
||||
回复载荷示例:
|
||||
|
||||
```
|
||||
给你。
|
||||
|
||||
[[tts:voiceId=pMsXgVXv3BLzUgSXRplE model=eleven_v3 speed=1.1]]
|
||||
[[tts:text]](笑) 再把这首歌读一遍。[[/tts:text]]
|
||||
[[tts:text]](笑)再把这首歌读一遍。[[/tts:text]]
|
||||
```
|
||||
|
||||
可用的指令键(启用时):
|
||||
|
||||
- `provider`(已注册的语音提供商 ID,例如 `openai`、`elevenlabs`、`google`、`gradium`、`minimax`、`microsoft`、`volcengine`、`vydra`、`xai` 或 `xiaomi`;需要 `allowProvider: true`)
|
||||
- `voice`(OpenAI、Gradium、Volcengine 或 Xiaomi 语音)、`voiceName` / `voice_name` / `google_voice`(Google 语音),或 `voiceId`(ElevenLabs / Gradium / MiniMax / xAI)
|
||||
- `model`(OpenAI TTS 模型、ElevenLabs model id、MiniMax 模型或 Xiaomi MiMo TTS 模型)或 `google_model`(Google TTS 模型)
|
||||
- `provider`(已注册的语音提供商 id,例如 `openai`、`elevenlabs`、`google`、`gradium`、`minimax`、`microsoft`、`volcengine`、`vydra`、`xai` 或 `xiaomi`;需要 `allowProvider: true`)
|
||||
- `voice`(OpenAI、Gradium、Volcengine 或 Xiaomi 的 voice)、`voiceName` / `voice_name` / `google_voice`(Google voice)或 `voiceId`(ElevenLabs / Gradium / MiniMax / xAI)
|
||||
- `model`(OpenAI TTS model、ElevenLabs model id、MiniMax model 或 Xiaomi MiMo TTS model)或 `google_model`(Google TTS model)
|
||||
- `stability`、`similarityBoost`、`style`、`speed`、`useSpeakerBoost`
|
||||
- `vol` / `volume`(MiniMax 音量,0-10)
|
||||
- `pitch`(MiniMax 整数音高,-12 到 12;在发起 MiniMax 请求前会截断小数值)
|
||||
- `pitch`(MiniMax 整数音高,-12 到 12;小数值在发送 MiniMax 请求前会被截断)
|
||||
- `emotion`(Volcengine 情感标签)
|
||||
- `applyTextNormalization`(`auto|on|off`)
|
||||
- `languageCode`(ISO 639-1)
|
||||
@ -659,7 +686,7 @@ Local CLI TTS 会在 Gateway 网关主机上运行已配置的命令。`args`
|
||||
}
|
||||
```
|
||||
|
||||
可选允许列表(启用提供商切换,同时保留其他参数可配置):
|
||||
可选的 allowlist(启用提供商切换,同时保留其他参数可配置):
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -675,44 +702,44 @@ Local CLI TTS 会在 Gateway 网关主机上运行已配置的命令。`args`
|
||||
}
|
||||
```
|
||||
|
||||
## 按用户的偏好设置
|
||||
## 每用户偏好设置
|
||||
|
||||
斜杠命令会将本地覆盖写入 `prefsPath`(默认:
|
||||
`~/.openclaw/settings/tts.json`,可通过 `OPENCLAW_TTS_PREFS` 或
|
||||
`messages.tts.prefsPath` 覆盖)。
|
||||
|
||||
存储的字段:
|
||||
存储字段:
|
||||
|
||||
- `enabled`
|
||||
- `provider`
|
||||
- `maxLength`(摘要阈值;默认 1500 个字符)
|
||||
- `summarize`(默认 `true`)
|
||||
|
||||
这些字段会覆盖该主机上来自 `messages.tts` 加上当前激活
|
||||
这些设置会覆盖该主机上来自 `messages.tts` 加上当前活动
|
||||
`agents.list[].tts` 块的生效配置。
|
||||
|
||||
## 输出格式(固定)
|
||||
|
||||
- **Feishu / Matrix / Telegram / WhatsApp**:语音便笺回复优先使用 Opus(ElevenLabs 的 `opus_48000_64`,OpenAI 的 `opus`)。
|
||||
- 48 kHz / 64 kbps 是语音消息较好的折中方案。
|
||||
- **Feishu / Matrix / Telegram / WhatsApp**:语音便笺回复优先使用 Opus(ElevenLabs 使用 `opus_48000_64`,OpenAI 使用 `opus`)。
|
||||
- 48 kHz / 64 kbps 是适合语音消息的折中选择。
|
||||
- **Feishu / WhatsApp**:当语音便笺回复生成为 MP3/WebM/WAV/M4A
|
||||
或其他可能的音频文件时,渠道插件会在发送原生语音消息前,使用 `ffmpeg` 将其转码为 48 kHz
|
||||
Ogg/Opus。WhatsApp 会通过带有 `ptt: true` 和
|
||||
`audio/ogg; codecs=opus` 的 Baileys `audio` 负载发送结果。如果转换失败,Feishu 会收到原始文件作为附件;WhatsApp 发送会失败,而不是发送不兼容的 PTT 负载。
|
||||
- **其他渠道**:MP3(ElevenLabs 的 `mp3_44100_128`,OpenAI 的 `mp3`)。
|
||||
或其他常见音频文件格式时,渠道插件会在发送原生语音消息前使用 `ffmpeg` 将其转码为 48 kHz
|
||||
Ogg/Opus。WhatsApp 通过 Baileys 的 `audio` 载荷配合 `ptt: true` 和
|
||||
`audio/ogg; codecs=opus` 发送结果。如果转换失败,Feishu 会收到原始文件作为附件;WhatsApp 发送将失败,而不会发布不兼容的 PTT 载荷。
|
||||
- **其他渠道**:MP3(ElevenLabs 使用 `mp3_44100_128`,OpenAI 使用 `mp3`)。
|
||||
- 44.1 kHz / 128 kbps 是语音清晰度的默认平衡点。
|
||||
- **MiniMax**:普通音频附件使用 MP3(`speech-2.8-hd` 模型,32 kHz 采样率)。对于 Feishu、Telegram 和 WhatsApp 等语音便笺目标,OpenClaw 会在投递前使用 `ffmpeg` 将 MiniMax MP3 转码为 48 kHz Opus。
|
||||
- **Xiaomi MiMo**:默认使用 MP3,配置后也可使用 WAV。对于 Feishu、Telegram 和 WhatsApp 等语音便笺目标,OpenClaw 会在投递前使用 `ffmpeg` 将 Xiaomi 输出转码为 48 kHz Opus。
|
||||
- **Local CLI**:使用已配置的 `outputFormat`。语音便笺目标会被转换为 Ogg/Opus,电话输出会通过 `ffmpeg` 转换为原始 16 kHz 单声道 PCM。
|
||||
- **Google Gemini**:Gemini API TTS 返回原始 24 kHz PCM。OpenClaw 会将其封装为 WAV 用于音频附件,将其转码为 48 kHz Opus 用于语音便笺目标,并直接返回 PCM 用于 Talk/电话。
|
||||
- **Xiaomi MiMo**:默认使用 MP3,或在配置时使用 WAV。对于 Feishu、Telegram 和 WhatsApp 等语音便笺目标,OpenClaw 会在投递前使用 `ffmpeg` 将 Xiaomi 输出转码为 48 kHz Opus。
|
||||
- **Local CLI**:使用已配置的 `outputFormat`。语音便笺目标会转换为 Ogg/Opus,电话输出会通过 `ffmpeg` 转换为原始 16 kHz 单声道 PCM。
|
||||
- **Google Gemini**:Gemini API TTS 返回原始 24 kHz PCM。OpenClaw 会将其封装为 WAV 用于音频附件,将其转码为 48 kHz Opus 用于语音便笺目标,并将 PCM 直接用于 Talk/电话。
|
||||
- **Gradium**:音频附件使用 WAV,语音便笺目标使用 Opus,电话使用 8 kHz 的 `ulaw_8000`。
|
||||
- **Inworld**:普通音频附件使用 MP3,语音便笺目标使用原生 `OGG_OPUS`,Talk/电话使用 22050 Hz 的原始 `PCM`。
|
||||
- **xAI**:默认使用 MP3;`responseFormat` 可以是 `mp3`、`wav`、`pcm`、`mulaw` 或 `alaw`。OpenClaw 使用 xAI 的批处理 REST TTS endpoint,并返回完整的音频附件;此提供商路径不使用 xAI 的流式 TTS WebSocket。此路径不支持原生 Opus 语音便笺格式。
|
||||
- **xAI**:默认使用 MP3;`responseFormat` 可以是 `mp3`、`wav`、`pcm`、`mulaw` 或 `alaw`。OpenClaw 使用 xAI 的批量 REST TTS endpoint,并返回完整的音频附件;此提供商路径不使用 xAI 的流式 TTS WebSocket。此路径不支持原生 Opus 语音便笺格式。
|
||||
- **Microsoft**:使用 `microsoft.outputFormat`(默认 `audio-24khz-48kbitrate-mono-mp3`)。
|
||||
- 内置传输接受 `outputFormat`,但并非所有格式都可从该服务获得。
|
||||
- 内置传输方式接受 `outputFormat`,但该服务并非所有格式都可用。
|
||||
- 输出格式值遵循 Microsoft Speech 输出格式(包括 Ogg/WebM Opus)。
|
||||
- Telegram `sendVoice` 接受 OGG/MP3/M4A;如果你需要有保证的 Opus 语音消息,请使用 OpenAI/ElevenLabs。
|
||||
- 如果已配置的 Microsoft 输出格式失败,OpenClaw 会回退并重试 MP3。
|
||||
- Telegram `sendVoice` 接受 OGG/MP3/M4A;如果你需要有保障的 Opus 语音消息,请使用 OpenAI/ElevenLabs。
|
||||
- 如果已配置的 Microsoft 输出格式失败,OpenClaw 会回退重试 MP3。
|
||||
|
||||
OpenAI/ElevenLabs 的输出格式按渠道固定(见上文)。
|
||||
|
||||
@ -721,39 +748,43 @@ OpenAI/ElevenLabs 的输出格式按渠道固定(见上文)。
|
||||
启用后,OpenClaw 会:
|
||||
|
||||
- 如果回复已包含媒体或 `MEDIA:` 指令,则跳过 TTS。
|
||||
- 跳过非常短的回复(少于 10 个字符)。
|
||||
- 跳过过短回复(少于 10 个字符)。
|
||||
- 启用时,使用 `agents.defaults.model.primary`(或 `summaryModel`)对长回复进行摘要。
|
||||
- 将生成的音频作为附件附加到回复中。
|
||||
- 将生成的音频附加到回复中。
|
||||
|
||||
如果回复超过 `maxLength`,且摘要已关闭(或摘要模型没有 API 密钥),则会跳过音频,并发送普通文本回复。
|
||||
如果回复超过 `maxLength` 且摘要关闭(或摘要模型没有 API 密钥),则会跳过音频,仅发送普通文本回复。
|
||||
|
||||
## 流程图
|
||||
|
||||
```
|
||||
回复 -> 已启用 TTS?
|
||||
否 -> 发送文本
|
||||
是 -> 是否有媒体 / MEDIA: / 过短?
|
||||
是 -> 发送文本
|
||||
否 -> 长度 > 限制?
|
||||
否 -> TTS -> 附加音频
|
||||
是 -> 已启用摘要?
|
||||
否 -> 发送文本
|
||||
是 -> 摘要(summaryModel 或 agents.defaults.model.primary)
|
||||
是 -> 是否包含媒体 / MEDIA: / 过短?
|
||||
是 -> 发送文本
|
||||
否 -> 长度 > 限制?
|
||||
否 -> TTS -> 附加音频
|
||||
是 -> 已启用摘要?
|
||||
否 -> 发送文本
|
||||
是 -> 摘要(summaryModel 或 agents.defaults.model.primary)
|
||||
-> TTS -> 附加音频
|
||||
```
|
||||
|
||||
## 斜杠命令用法
|
||||
|
||||
只有一个命令:`/tts`。
|
||||
启用详情见 [斜杠命令](/zh-CN/tools/slash-commands)。
|
||||
启用详情请参阅 [斜杠命令](/zh-CN/tools/slash-commands)。
|
||||
|
||||
Discord 说明:`/tts` 是 Discord 的内置命令,因此 OpenClaw 会在该平台上注册
|
||||
`/voice` 作为原生命令。文本形式的 `/tts ...` 仍然可用。
|
||||
Discord 说明:`/tts` 是 Discord 内置命令,因此 OpenClaw 会在该平台注册
|
||||
`/voice` 作为原生命令。但文本形式的 `/tts ...` 仍然可用。
|
||||
|
||||
```
|
||||
/tts off
|
||||
/tts on
|
||||
/tts status
|
||||
/tts chat on
|
||||
/tts chat off
|
||||
/tts chat default
|
||||
/tts latest
|
||||
/tts provider openai
|
||||
/tts limit 2000
|
||||
/tts summary off
|
||||
@ -762,25 +793,29 @@ Discord 说明:`/tts` 是 Discord 的内置命令,因此 OpenClaw 会在该
|
||||
|
||||
说明:
|
||||
|
||||
- 命令需要授权发送者(allowlist/owner 规则仍然适用)。
|
||||
- 命令需要已授权的发送者(allowlist/owner 规则仍然适用)。
|
||||
- 必须启用 `commands.text` 或原生命令注册。
|
||||
- 配置 `messages.tts.auto` 接受 `off|always|inbound|tagged`。
|
||||
- `/tts on` 会将本地 TTS 偏好写为 `always`;`/tts off` 会将其写为 `off`。
|
||||
- 如果你想使用 `inbound` 或 `tagged` 作为默认值,请使用配置。
|
||||
- `limit` 和 `summary` 存储在本地 prefs 中,而不是主配置中。
|
||||
- `/tts audio` 会生成一次性的音频回复(不会切换 TTS 为开启)。
|
||||
- `/tts chat on|off|default` 会为当前聊天写入会话范围的自动 TTS 覆盖。
|
||||
- 当你希望默认使用 `inbound` 或 `tagged` 时,请使用配置。
|
||||
- `limit` 和 `summary` 存储在本地偏好中,而不是主配置中。
|
||||
- `/tts audio` 会生成一次性音频回复(不会切换 TTS 为开启)。
|
||||
- `/tts latest` 会读取当前会话转录中的最新 assistant 回复,并将其作为音频发送一次。它只会在会话条目中存储该回复的哈希值,以抑制重复的语音发送。
|
||||
- `/tts status` 包含最近一次尝试的回退可见性:
|
||||
- 成功回退:`Fallback: <primary> -> <used>` 加 `Attempts: ...`
|
||||
- 失败:`Error: ...` 加 `Attempts: ...`
|
||||
- 成功回退:`Fallback: <primary> -> <used>` 加上 `Attempts: ...`
|
||||
- 失败:`Error: ...` 加上 `Attempts: ...`
|
||||
- 详细诊断:`Attempt details: provider:outcome(reasonCode) latency`
|
||||
- OpenAI 和 ElevenLabs API 失败现在会包含已解析的提供商错误详情和请求 ID(当提供商返回时),这些信息会显示在 TTS 错误/日志中。
|
||||
- `/status` 会在启用 TTS 时显示当前活动的 TTS 模式,以及已配置的提供商、model、voice 和已净化的自定义 endpoint 元数据。
|
||||
- OpenAI 和 ElevenLabs 的 API 故障现在会包含已解析的提供商错误详情和请求 id(如果提供商返回),这些信息会显示在 TTS 错误/日志中。
|
||||
|
||||
## 智能体工具
|
||||
|
||||
`tts` 工具会将文本转换为语音,并返回用于回复投递的音频附件。当渠道是 Feishu、Matrix、Telegram 或 WhatsApp 时,音频会以语音消息而不是文件附件的形式投递。
|
||||
在此路径上,如果 `ffmpeg` 可用,Feishu 和 WhatsApp 可以对非 Opus 的 TTS 输出进行转码。
|
||||
WhatsApp 会通过 Baileys 以 PTT 语音便笺(带有 `ptt: true` 的 `audio`)发送音频,并将可见文本与 PTT 音频分开发送,因为客户端并不总是能稳定显示语音便笺上的字幕。
|
||||
它接受可选的 `channel` 和 `timeoutMs` 字段;`timeoutMs` 是按调用设置的提供商请求超时,单位为毫秒。
|
||||
`tts` 工具会将文本转换为语音,并返回用于回复投递的音频附件。当渠道为 Feishu、Matrix、Telegram 或 WhatsApp 时,音频会作为语音消息而不是文件附件投递。
|
||||
当 `ffmpeg` 可用时,Feishu 和 WhatsApp 可在此路径上转码非 Opus 的 TTS 输出。
|
||||
WhatsApp 通过 Baileys 将音频作为 PTT 语音便笺发送(`audio` 搭配
|
||||
`ptt: true`),并将可见文本与 PTT 音频分开发送,因为客户端对语音便笺字幕的渲染并不一致。
|
||||
它接受可选的 `channel` 和 `timeoutMs` 字段;`timeoutMs` 是每次调用的提供商请求超时,单位为毫秒。
|
||||
|
||||
## Gateway 网关 RPC
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user