chore(i18n): refresh zh-CN translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-24 16:37:57 +00:00
parent e182e2b80d
commit 9aef37d78d
5 changed files with 684 additions and 694 deletions

View File

@ -1,54 +1,54 @@
---
read_when:
- 设置无需按任务逐次提示即可运行的自主智能体工作流
- 定义智能体可以独立执行的操作与需要人工批准的事项
- 为多程序智能体建立清晰边界和升级规则的结构设计
summary: 为自智能体程序定义永久运行权限
- 设置无需逐任务提示即可运行的自治智能体工作流
- 定义智能体可以独立完成的事项,以及哪些事项需要人工批准
- 构建多程序智能体,并明确边界和升级规则
summary: 为自智能体程序定义永久运行权限
title: 长期指令
x-i18n:
generated_at: "2026-04-24T16:21:09Z"
generated_at: "2026-04-24T16:35:15Z"
model: gpt-5.4
provider: openai
source_hash: 6d95024b29d04638be610a9fe3ca9651e8704b2b03ea16a3112cf31a7287c386
source_hash: 4a18777284a12e99b2e9f1ce660a0dc4d18ba5782d6a6a6673b495ab32b2d8cf
source_path: automation/standing-orders.md
workflow: 15
---
长期指令会为你智能体的特定程序授予**永久运行权限**。你不必每次都单独下达任务指令,而是定义具有明确范围、触发条件和升级规则的程序——智能体会在这些边界内自主执行。
长期指令会为你的智能体授予针对已定义程序的**永久运行权限**。你不必每次都单独下达任务指令,而是通过明确范围、触发条件和升级规则来定义程序——然后智能体会在这些边界内自主执行。
就像你每周五都对助手说一次“发送每周报告”,与授予长期权限之间的区别:“每周报告由你负责。每周五汇总并发送,只有在发现异常时才升级给我处理。”
相当于:不是每周五都对助手说“发送每周报告”,而是授予长期权限:“每周报告由你负责。每周五完成汇总并发送,只有在发现异常时才升级给我处理。”
## 为什么使用长期指令?
## 为什么使用长期指令?
**没有长期指令时:**
- 你必须为每项任务提示智能体
- 你必须为每个任务都提示智能体
- 智能体会在请求之间处于空闲状态
- 例行工作被遗忘或延迟
- 你会成为瓶颈
- 例行工作容易被遗忘或延迟
- 你会成为整个流程的瓶颈
**有长期指令时**
**有了长期指令后**
- 智能体会在已定义边界内自主执行
- 智能体会在已定义边界内自主执行
- 例行工作会按计划完成,无需提示
- 只有异常和审批事项才需要你介入
- 你只需要参与异常情况和审批事项
- 智能体会高效利用空闲时间
## 它们如何工作
长期指令定义在你的[智能体工作区](/zh-CN/concepts/agent-workspace)文件中。推荐做法是将它们直接写入 `AGENTS.md`每次会话都会自动注入),这样智能体始终能在上下文中获取这些指令。对于较大的配置,你也可以将其放在专门的文件中,例如 `standing-orders.md`,然后在 `AGENTS.md` 中引用它。
长期指令定义在你的[智能体工作区](/zh-CN/concepts/agent-workspace)文件中。推荐做法是将它们直接写入 `AGENTS.md`该文件会在每次会话中自动注入),这样智能体始终会在上下文中看到这些指令。对于更大的配置,你也可以将其放在专用文件中,例如 `standing-orders.md`,然后在 `AGENTS.md` 中引用它。
每个程序都应指定:
1. **范围**——智能体被授权执行哪些操作
2. **触发条件**——何时执行(计划、事件或条件)
3. **审批关卡**——哪些操作在执行前需要人工签字确认
4. **升级规则**——何时停止并请求帮助
1. **范围** —— 智能体被授权执行哪些内容
2. **触发条件** —— 何时执行(计划、事件触发或条件触发
3. **审批关卡** —— 哪些操作需要先获得人工签字确认
4. **升级规则** —— 何时停止并请求帮助
智能体会在每次会话中通过工作区引导文件加载这些指令(有关自动注入文件的完整列表,请参见[智能体工作区](/zh-CN/concepts/agent-workspace)),并结合 [cron jobs](/zh-CN/automation/cron-jobs) 对基于时间的执行进行约束
智能体会在每次会话中通过工作区引导文件加载这些指令(完整自动注入文件列表参见[智能体工作区](/zh-CN/concepts/agent-workspace)),并结合 [cron jobs](/zh-CN/automation/cron-jobs) 来执行基于时间的强制调度
<Tip>
将长期指令放在 `AGENTS.md` 中,以确保它们在每次会话中都会被加载。工作区引导机制会自动注入 `AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md` 和 `MEMORY.md` —— 但不会自动注入子目录中的任意文件。
把长期指令放在 `AGENTS.md` 中,以确保它们会在每次会话中加载。工作区引导流程会自动注入 `AGENTS.md`、`SOUL.md`、`TOOLS.md`、`IDENTITY.md`、`USER.md`、`HEARTBEAT.md`、`BOOTSTRAP.md` 和 `MEMORY.md`——但不会自动注入子目录中的任意文件。
</Tip>
## 长期指令的结构
@ -78,7 +78,7 @@ x-i18n:
## 长期指令 + Cron Jobs
长期指令定义智能体被授权做**什么**。[Cron Jobs](/zh-CN/automation/cron-jobs) 定义它**何时**执行。二者配合使用
长期指令定义智能体被授权做**什么**。[Cron Jobs](/zh-CN/automation/cron-jobs) 定义事情在**什么时候**发生。两者协同工作
```
Standing Order: "You own the daily inbox triage"
@ -88,7 +88,7 @@ Cron Job (8 AM daily): "Execute inbox triage per standing orders"
Agent: Reads standing orders → executes steps → reports results
```
Cron job 提示词应引用长期指令,而不是重复其内容:
`cron job` 提示应当引用长期指令,而不是重复书写其内容:
```bash
openclaw cron add \
@ -104,7 +104,7 @@ openclaw cron add \
## 示例
### 示例 1内容与社交媒体每周周期
### 示例 1内容与社交媒体每周循环
```markdown
## Program: Content & Social Media
@ -153,7 +153,7 @@ openclaw cron add \
- Failed processing after 2 retries: report failure, do not guess
```
### 示例 3监控与告警持续行)
### 示例 3监控与告警持续行)
```markdown
## Program: System Monitoring
@ -179,13 +179,13 @@ openclaw cron add \
| Channel offline | Log and retry next cycle | If offline > 2 hours |
```
## 执行-验证-报模式
## 执行-验证-报模式
长期指令在与严格的执行纪律结合时效果最佳。长期指令中的每项任务都应遵循以下循环:
长期指令在与严格的执行纪律结合时效果最好。长期指令中的每个任务都应遵循以下循环:
1. **执行**——完成实际工作(不要只是确认收到指令)
2. **验证**——确认结果正确(文件存在、消息已送达、数据已解析)
3. **报告**——告知所有者已完成什么,以及验证了什么
1. **执行** —— 完成实际工作(不要只是确认收到指令)
2. **验证** —— 确认结果正确无误(文件存在、消息已送达、数据已解析)
3. **汇报** —— 告诉所有者你做了什么,以及验证了什么
```markdown
### Execution Rules
@ -198,11 +198,11 @@ openclaw cron add \
- Never retry indefinitely — 3 attempts max, then escalate.
```
这种模式可以防止最常见的智能体失误:确认了任务,但实际上没有完成
这种模式可以防止智能体最常见的失败方式:只确认任务,却没有真正完成任务
## 多程序架构
对于管理多个事项的智能体,应将长期指令组织为彼此独立的程序,并明确边界:
对于需要管理多个事项的智能体,应将长期指令组织为多个独立程序,并明确它们之间的边界:
```markdown
## Program 1: [Domain A] (Weekly)
@ -225,33 +225,33 @@ openclaw cron add \
每个程序都应具备:
- 自己的**触发节奏**(每周、每月、事件驱动、持续行)
- 自己的**触发节奏**(每周、每月、事件驱动、持续行)
- 自己的**审批关卡**(有些程序比其他程序需要更多监督)
- 清晰的**边界**(智能体应知道一个程序何时结束、另一个程序何时开始)
- 清晰的**边界**(智能体应当知道一个程序在哪里结束,另一个程序从哪里开始)
## 最佳实践
### 应该
### 建议这样
- 从较窄的权限范围开始,并随着信任建立逐步扩大
- 一开始只授予较窄的权限,并随着信任建立逐步扩大
- 为高风险操作定义明确的审批关卡
- 包含“禁止执行的事项”部分——边界和权限同样重要
- 结合 cron jobs 以确保基于时间的执行可靠发生
- 每周查看智能体日志,验证长期指令是否得到遵守
- 随着需求演变更新长期指令——它们是持续演进的文档
- 加入“不要做什么”部分——边界和权限同样重要
- 结合 Cron Jobs 使用,以实现可靠的定时执行
- 每周检查智能体日志,确认长期指令正在被正确遵循
- 随着需求演变更新长期指令——它们是动态文档
### 避免
### 避免这样做
- 第一天就授予过宽权限(“做你认为最好的任何事”)
- 跳过升级规则——每个程序都需要“何时停止并询问”的条款
- 假设智能体会记住口头指令——把所有内容写进文件中
- 将多个事项混在同一个程序里——不同领域应拆分为不同程序
- 忘记用 cron jobs 强制执行——没有触发条件的长期指令只会沦为建议
- 第一天就授予过宽权限(“你觉得怎么最好就怎么做”)
- 跳过升级规则——每个程序都需要“什么时候停止并询问”的条款
- 假设智能体会记住口头指令——把所有内容都写进文件里
- 在同一个程序中混合多个事项——不同领域应拆分为不同程序
- 忘记通过 `cron jobs` 强制执行——没有触发器的长期指令只会变成建议
## 相关内容
- [Automation & Tasks](/zh-CN/automation) —— 所有自动化机制总览
- [Cron Jobs](/zh-CN/automation/cron-jobs) —— 长期指令的计划执行机制
- [Automation & Tasks](/zh-CN/automation) —— 各类自动化机制总览
- [Cron Jobs](/zh-CN/automation/cron-jobs) —— 长期指令的调度执行机制
- [Hooks](/zh-CN/automation/hooks) —— 用于智能体生命周期事件的事件驱动脚本
- [Webhooks](/zh-CN/automation/cron-jobs#webhooks) —— 入站 HTTP 事件触发器
- [Agent Workspace](/zh-CN/concepts/agent-workspace) —— 长期指令的存放位置包括完整的自动注入引导文件列表AGENTS.md、SOUL.md 等)

View File

@ -1,32 +1,32 @@
---
read_when:
- 理解 OpenClaw 中 Pi SDK 集成设计
- 修改 Pi 的智能体会话生命周期、工具链或提供商接线
- 修改 Pi 的智能体会话生命周期、工具链或提供商接线方式
summary: OpenClaw 内置 Pi 智能体集成的架构与会话生命周期
title: Pi 集成架构
x-i18n:
generated_at: "2026-04-24T15:13:09Z"
generated_at: "2026-04-24T16:35:18Z"
model: gpt-5.4
provider: openai
source_hash: 0c0b019ff6d35f6fdcd57b56edd1945e62a96bb4b34e312d7fb0c627f01287f1
source_hash: 7ec260fd3e2726190ed7aa60e249b739689f2d42d230f52fa93a43cbbf90ea06
source_path: pi.md
workflow: 15
---
本文档介绍了 OpenClaw 如何集成 [pi-coding-agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent) 及其同级软件包(`pi-ai`、`pi-agent-core`、`pi-tui`),以提供其 AI 智能体能力。
本文档介绍了 OpenClaw 如何 [pi-coding-agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent) 及其同级包(`pi-ai`、`pi-agent-core`、`pi-tui`集成,以提供其 AI 智能体能力。
## 概览
OpenClaw 使用 pi SDK 将一个 AI 编码智能体嵌入到其消息 Gateway 网关架构中。OpenClaw 并不是将 pi 作为子进程启动,也不是使用 RPC 模式,而是通过 `createAgentSession()` 直接导入并实例化 pi 的 `AgentSession`。这种内嵌式方案提供了:
OpenClaw 使用 pi SDK 将一个 AI 编码智能体嵌入到其消息 Gateway 网关架构中。OpenClaw 不会将 pi 作为子进程启动,也不会使用 RPC 模式,而是通过 `createAgentSession()` 直接导入并实例化 pi 的 `AgentSession`。这种内嵌方式提供了:
- 对会话生命周期和事件处理的完全控制
- 自定义工具注入(消息、沙箱、渠道特定操作)
- 自定义工具注入(消息传递、沙箱、特定渠道操作)
- 按渠道/上下文自定义系统提示词
- 支持分支/压缩的会话持久化
- 具备故障转移能力的多账户认证配置轮换
- 提供商无关的模型切换
- 带故障转移的多账号认证配置轮换
- 提供商无关的模型切换
## 软件包依赖
## 包依赖
```json
{
@ -37,12 +37,12 @@ OpenClaw 使用 pi SDK 将一个 AI 编码智能体嵌入到其消息 Gateway
}
```
| 软件包 | 用途 |
| ----------------- | ------------------------------------------------------------------------------------------------------ |
| `pi-ai` | 核心 LLM 抽象:`Model`、`streamSimple`、消息类型、提供商 API |
| `pi-agent-core` | 智能体循环、工具执行、`AgentMessage` 类型 |
| Package | 用途 |
| ----------------- | ---- |
| `pi-ai` | 核心 LLM 抽象:`Model`、`streamSimple`、消息类型、提供商 API |
| `pi-agent-core` | 智能体循环、工具执行、`AgentMessage` 类型 |
| `pi-coding-agent` | 高层 SDK`createAgentSession`、`SessionManager`、`AuthStorage`、`ModelRegistry`、内置工具 |
| `pi-tui` | 终端 UI 组件(用于 OpenClaw 的本地 TUI 模式) |
| `pi-tui` | 终端 UI 组件(用于 OpenClaw 的本地 TUI 模式) |
## 文件结构
@ -52,24 +52,24 @@ src/agents/
├── pi-embedded-runner/
│ ├── run.ts # 主入口runEmbeddedPiAgent()
│ ├── run/
│ │ ├── attempt.ts # 包含会话设置的单次尝试逻辑
│ │ ├── attempt.ts # 会话设置的单次尝试逻辑
│ │ ├── params.ts # RunEmbeddedPiAgentParams 类型
│ │ ├── payloads.ts # 从运行结果构建响应负载
│ │ ├── images.ts # 视觉模型图像注入
│ │ └── types.ts # EmbeddedRunAttemptResult
│ ├── abort.ts # Abort 错误检测
│ ├── abort.ts # 中止错误检测
│ ├── cache-ttl.ts # 用于上下文裁剪的缓存 TTL 跟踪
│ ├── compact.ts # 手动/自动压缩逻辑
│ ├── extensions.ts # 为嵌入式运行加载 pi 扩展
│ ├── extensions.ts # 为嵌运行加载 pi 扩展
│ ├── extra-params.ts # 提供商特定的流式参数
│ ├── google.ts # Google/Gemini 轮次顺序修复
│ ├── history.ts # 历史记录限制(私信 vs 群组)
│ ├── history.ts # 历史限制(私信 vs 群组)
│ ├── lanes.ts # 会话/全局命令通道
│ ├── logger.ts # 子系统日志记录器
│ ├── model.ts # 通过 ModelRegistry 进行模型解析
│ ├── runs.ts # 活跃运行跟踪、Abort、队列
│ ├── model.ts # 通过 ModelRegistry 解析模型
│ ├── runs.ts # 活动运行跟踪、中止、排队
│ ├── sandbox-info.ts # 用于系统提示词的沙箱信息
│ ├── session-manager-cache.ts # `SessionManager` 实例缓存
│ ├── session-manager-cache.ts # SessionManager 实例缓存
│ ├── session-manager-init.ts # 会话文件初始化
│ ├── system-prompt.ts # 系统提示词构建器
│ ├── tool-split.ts # 将工具拆分为 builtIn 与 custom
@ -80,16 +80,16 @@ src/agents/
├── pi-embedded-subscribe.handlers.ts # 事件处理器工厂
├── pi-embedded-subscribe.handlers.lifecycle.ts
├── pi-embedded-subscribe.handlers.types.ts
├── pi-embedded-block-chunker.ts # 流式分块回复切
├── pi-embedded-block-chunker.ts # 流式块回复分
├── pi-embedded-messaging.ts # 消息工具发送跟踪
├── pi-embedded-helpers.ts # 错误分类、轮次验
├── pi-embedded-helpers.ts # 错误分类、轮次
├── pi-embedded-helpers/ # 辅助模块
├── pi-embedded-utils.ts # 格式化工具函数
├── pi-embedded-utils.ts # 格式化工具
├── pi-tools.ts # createOpenClawCodingTools()
├── pi-tools.abort.ts # 面向工具的 AbortSignal 封
├── pi-tools.policy.ts # 工具 allowlist/denylist 策略
├── pi-tools.read.ts # Read 工具自定义
├── pi-tools.schema.ts # 工具 schema 规范
├── pi-tools.abort.ts # 工具的 AbortSignal 包
├── pi-tools.policy.ts # 工具允许列表/拒绝列表策略
├── pi-tools.read.ts # read 工具自定义
├── pi-tools.schema.ts # 工具 schema 标准
├── pi-tools.types.ts # AnyAgentTool 类型别名
├── pi-tool-definition-adapter.ts # AgentTool -> ToolDefinition 适配器
├── pi-settings.ts # 设置覆盖
@ -101,22 +101,22 @@ src/agents/
├── model-auth.ts # 认证配置解析
├── auth-profiles.ts # 配置存储、冷却、故障转移
├── model-selection.ts # 默认模型解析
├── models-config.ts # `models.json` 生成
├── models-config.ts # models.json 生成
├── model-catalog.ts # 模型目录缓存
├── context-window-guard.ts # 上下文窗口验
├── failover-error.ts # `FailoverError`
├── context-window-guard.ts # 上下文窗口
├── failover-error.ts # FailoverError 类
├── defaults.ts # DEFAULT_PROVIDER、DEFAULT_MODEL
├── system-prompt.ts # buildAgentSystemPrompt()
├── system-prompt-params.ts # 系统提示词参数解析
├── system-prompt-report.ts # 调试报告生成
├── tool-summaries.ts # 工具描述摘要
├── tool-policy.ts # 工具策略解析
├── transcript-policy.ts # 转录验策略
├── skills.ts # Skills 快照/提示词构建
├── skills/ # Skills 子系统
├── transcript-policy.ts # 转录验策略
├── skills.ts # Skill 快照/提示词构建
├── skills/ # Skill 子系统
├── sandbox.ts # 沙箱上下文解析
├── sandbox/ # 沙箱子系统
├── channel-tools.ts # 渠道特定工具注入
├── channel-tools.ts # 特定渠道工具注入
├── openclaw-tools.ts # OpenClaw 特定工具
├── bash-tools.ts # exec/process 工具
├── apply-patch.ts # apply_patch 工具OpenAI
@ -134,7 +134,7 @@ src/agents/
└── ...
```
渠道特定的消息操作运行时现在位于插件所属的扩展目录中,而不再位于 `src/agents/tools` 下,例如:
特定渠道的消息操作运行时现在位于插件拥有的扩展目录中,而不再位于 `src/agents/tools` 下,例如:
- Discord 插件操作运行时文件
- Slack 插件操作运行时文件
@ -143,7 +143,7 @@ src/agents/
## 核心集成流程
### 1. 运行嵌入式智能体
### 1. 运行嵌智能体
主入口是 `pi-embedded-runner/run.ts` 中的 `runEmbeddedPiAgent()`
@ -167,9 +167,9 @@ const result = await runEmbeddedPiAgent({
});
```
### 2. 会话创建
### 2. 创建会话
`runEmbeddedAttempt()`(由 `runEmbeddedPiAgent()` 调用)内部,使用 pi SDK
`runEmbeddedAttempt()`(由 `runEmbeddedPiAgent()` 调用)内部,使用 pi SDK
```typescript
import {
@ -206,7 +206,7 @@ applySystemPromptOverrideToSession(session, systemPromptOverride);
### 3. 事件订阅
`subscribeEmbeddedPiSession()` 订阅 pi 的 `AgentSession` 事件:
`subscribeEmbeddedPiSession()` 订阅 pi 的 `AgentSession` 事件:
```typescript
const subscription = subscribeEmbeddedPiSession({
@ -231,33 +231,33 @@ const subscription = subscribeEmbeddedPiSession({
- `agent_start` / `agent_end`
- `compaction_start` / `compaction_end`
### 4. 提示输入
### 4. 提示词发送
设置完成后,会向会话发送提示:
完成设置后,会向会话发送提示
```typescript
await session.prompt(effectivePrompt, { images: imageResult.images });
```
SDK 会处理完整的智能体循环:发送给 LLM、执行工具调用、流式传输响应。
SDK 会处理完整的智能体循环:发送到 LLM、执行工具调用、流式返回响应。
图像注入仅限当前提示OpenClaw 会从当前提示中加载图像引用,并通过 `images` 仅传递给该轮。它不会重新扫描更早的历史轮次来重新注入图像负载。
图像注入是提示词局部的OpenClaw 会从当前提示词中加载图像引用,并仅通过 `images` 为当前轮次传递它们。它不会重新扫描更早的历史轮次来重新注入图像负载。
## 工具架构
### 工具流水线
1. **基础工具**pi 的 `codingTools`read、bash、edit、write
2. **自定义替换**OpenClaw `exec`/`process` 替换 bash,并为沙箱自定义 read/edit/write
3. **OpenClaw 工具**:消息、浏览器、画布、会话、cron、Gateway 网关
2. **自定义替换**OpenClaw 将 bash 替换为 `exec`/`process`,并为沙箱自定义 read/edit/write
3. **OpenClaw 工具**:消息传递、浏览器、画布、会话、定时任务、Gateway 网关
4. **渠道工具**Discord/Telegram/Slack/WhatsApp 特定操作工具
5. **策略过滤**配置、提供商、智能体、群组、沙箱策略过滤工具
6. **Schema 规范化**:针对 Gemini/OpenAI 的特殊情况清理 schema
7. **AbortSignal 封装**:封装工具以支持 abort signals
5. **策略过滤**根据配置、提供商、智能体、群组、沙箱策略过滤工具
6. **Schema 标准化**:为处理 Gemini/OpenAI 的特殊行为清理 schema
7. **AbortSignal 包装**:包装工具以支持中止信号
### 工具定义适配器
pi-agent-core 的 `AgentTool` 与 pi-coding-agent 的 `ToolDefinition``execute` 签名上不同。`pi-tool-definition-adapter.ts` 中的适配器负责桥接这一差异:
pi-agent-core 的 `AgentTool` 具有与 pi-coding-agent 的 `ToolDefinition` 不同的 `execute` 签名。`pi-tool-definition-adapter.ts` 中的适配器会桥接这一差异:
```typescript
export function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] {
@ -276,7 +276,7 @@ export function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] {
### 工具拆分策略
`splitSdkTools()` 通过 `customTools` 传递所有工具:
`splitSdkTools()` 通过 `customTools` 传递所有工具:
```typescript
export function splitSdkTools(options: { tools: AnyAgentTool[]; sandboxEnabled: boolean }) {
@ -287,13 +287,13 @@ export function splitSdkTools(options: { tools: AnyAgentTool[]; sandboxEnabled:
}
```
确保 OpenClaw 的策略过滤、沙箱集成和扩展工具集在各个提供商之间保持一致。
这确保 OpenClaw 的策略过滤、沙箱集成和扩展工具集在各个提供商之间保持一致。
## 系统提示词构建
系统提示词在 `buildAgentSystemPrompt()``system-prompt.ts`)中构建。它会组装一个完整提示词,其中包含 Tooling、Tool Call Style、安全护栏、OpenClaw CLI 参考、Skills、文档、工作区、沙箱、消息、回复标签、语气、静默回复、心跳、运行时元数据,以及在启用时包含的 Memory 和 Reactions还可包含可选的上下文文件和额外系统提示词内容。用于子智能体的最小提示词模式会对这些部分进行裁剪。
系统提示词在 `buildAgentSystemPrompt()``system-prompt.ts`)中构建。它会组装一个完整提示词,其中包含 Tooling、Tool Call Style、安全护栏、OpenClaw CLI 参考、Skills、文档、工作区、沙箱、消息传递、回复标签、语气、静默回复、心跳、运行时元数据等部分,并在启用时加入 Memory 和 Reactions以及可选的上下文文件和额外系统提示词内容。对于子智能体使用的最小化提示词模式这些部分会被裁剪。
系统提示词会在创建会话后通过 `applySystemPromptOverrideToSession()` 应用:
提示词会在会话创建后通过 `applySystemPromptOverrideToSession()` 应用:
```typescript
const systemPromptOverride = createSystemPromptOverride(appendPrompt);
@ -304,17 +304,17 @@ applySystemPromptOverrideToSession(session, systemPromptOverride);
### 会话文件
会话是具有树状结构的 JSONL 文件(通过 id/parentId 链接)。Pi 的 `SessionManager` 负责持久化:
会话文件是具有树结构(通过 id/parentId 关联)的 JSONL 文件。Pi 的 `SessionManager` 负责持久化:
```typescript
const sessionManager = SessionManager.open(params.sessionFile);
```
OpenClaw 通过 `guardSessionManager()` 对其进行包装,以保证工具结果安全。
OpenClaw 通过 `guardSessionManager()` 对其进行封装,以保障工具结果安全。
### 会话缓存
`session-manager-cache.ts` 会缓存 `SessionManager` 实例,以避免重复解析文件:
`session-manager-cache.ts` 会缓存 SessionManager 实例,以避免重复解析文件:
```typescript
await prewarmSessionFile(params.sessionFile);
@ -322,13 +322,13 @@ sessionManager = SessionManager.open(params.sessionFile);
trackSessionManagerAccess(params.sessionFile);
```
### 历史记录限制
### 历史限制
`limitHistoryTurns()` 会根据渠道类型(私信群组)裁剪对话历史。
`limitHistoryTurns()` 会根据渠道类型(私信群组)裁剪对话历史。
### 压缩
当上下文溢出时会触发自动压缩。常见的溢出特征包括 `request_too_large`、`context length exceeded`、`input exceeds the maximum number of tokens`、`input token count exceeds the maximum number of input tokens`、`input is too long for the model`,以及 `ollama error: context length exceeded`。`compactEmbeddedPiSessionDirect()` 负责处理手动压缩:
当上下文溢出时会触发自动压缩。常见的溢出特征包括 `request_too_large`、`context length exceeded`、`input exceeds the maximum number of tokens`、`input token count exceeds the maximum number of input tokens`、`input is too long for the model` `ollama error: context length exceeded`。`compactEmbeddedPiSessionDirect()` 负责处理手动压缩:
```typescript
const compactResult = await compactEmbeddedPiSessionDirect({
@ -340,14 +340,14 @@ const compactResult = await compactEmbeddedPiSessionDirect({
### 认证配置
OpenClaw 维护一个认证配置存储,每个提供商可对应多个 API 密钥
OpenClaw 为每个提供商维护一个支持多个 API 密钥的认证配置存储
```typescript
const authStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
const profileOrder = resolveAuthProfileOrder({ cfg, store: authStore, provider, preferredProfile });
```
配置在失败时会轮换,并带有冷却跟踪
配置会在失败时结合冷却跟踪进行轮换
```typescript
await markAuthProfileFailure({ store, profileId, reason, cfg, agentDir });
@ -372,7 +372,7 @@ authStorage.setRuntimeApiKey(model.provider, apiKeyInfo.apiKey);
### 故障转移
配置后,`FailoverError` 会触发模型回退
当已配置回退时,`FailoverError` 会触发模型故障转移
```typescript
if (fallbackConfigured && isFailoverErrorMessage(errorText)) {
@ -388,11 +388,11 @@ if (fallbackConfigured && isFailoverErrorMessage(errorText)) {
## Pi 扩展
OpenClaw 会加载自定义 pi 扩展,以支持专门行为:
OpenClaw 会加载自定义 pi 扩展来实现特定行为:
### 压缩保护
`src/agents/pi-hooks/compaction-safeguard.ts` 为压缩添加护栏,包括自适应 token 预算,以及工具失败和文件操作摘要:
`src/agents/pi-hooks/compaction-safeguard.ts` 会为压缩增加护栏,包括自适应 token 预算,以及工具失败和文件操作摘要:
```typescript
if (resolveCompactionMode(params.cfg) === "safeguard") {
@ -403,7 +403,7 @@ if (resolveCompactionMode(params.cfg) === "safeguard") {
### 上下文裁剪
`src/agents/pi-hooks/context-pruning.ts` 实现基于缓存 TTL 的上下文裁剪:
`src/agents/pi-hooks/context-pruning.ts` 实现基于缓存 TTL 的上下文裁剪:
```typescript
if (cfg?.agents?.defaults?.contextPruning?.mode === "cache-ttl") {
@ -419,28 +419,28 @@ if (cfg?.agents?.defaults?.contextPruning?.mode === "cache-ttl") {
## 流式传输与分块回复
### 分块切分
### 分块处理
`EmbeddedBlockChunker` 负责将流式文本理为离散的回复块:
`EmbeddedBlockChunker` 负责将流式文本理为离散的回复块:
```typescript
const blockChunker = blockChunking ? new EmbeddedBlockChunker(blockChunking) : null;
```
### Thinking/Final 标签剥离
### 思考/最终标签剥离
流式输出会经过处理,以剥离 `<think>`/`<thinking>` 块并提取 `<final>` 内容:
```typescript
const stripBlockTags = (text: string, state: { thinking: boolean; final: boolean }) => {
// 剥离 <think>...</think> 内容
// 如果 enforceFinalTag 为真,则只返回 <final>...</final> 内容
// 如果 enforceFinalTag则只返回 <final>...</final> 内容
};
```
### 回复指令
会解析并提取诸如 `[[media:url]]`、`[[voice]]`、`[[reply:id]]` 之类的回复指令:
类似 `[[media:url]]`、`[[voice]]`、`[[reply:id]]` 的回复指令会被解析和提取
```typescript
const { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDirectives(chunk);
@ -450,20 +450,20 @@ const { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDi
### 错误分类
`pi-embedded-helpers.ts` 会对错误进行分类,以便进行当处理:
`pi-embedded-helpers.ts` 会对错误进行分类,以便进行当处理:
```typescript
isContextOverflowError(errorText) // 上下文过大
isCompactionFailureError(errorText) // 压缩失败
isAuthAssistantError(lastAssistant) // 认证失败
isRateLimitAssistantError(...) // 命中速率限制
isFailoverAssistantError(...) // 应行故障转移
isRateLimitAssistantError(...) // 遇到速率限制
isFailoverAssistantError(...) // 应行故障转移
classifyFailoverReason(errorText) // "auth" | "rate_limit" | "quota" | "timeout" | ...
```
### Thinking Level 回退
### 思考等级回退
如果某个 Thinking Level 不受支持,则会回退:
如果某个思考等级不受支持,则会回退:
```typescript
const fallbackThinking = pickFallbackThinkingLevel({
@ -490,7 +490,7 @@ const sandbox = await resolveSandboxContext({
if (sandboxRoot) {
// 使用沙箱隔离的 read/edit/write 工具
// Exec 在容器中运行
// Browser 使用 bridge URL
// Browser 使用桥接 URL
}
```
@ -499,21 +499,21 @@ if (sandboxRoot) {
### Anthropic
- 拒绝魔法字符串清理
- 连续角色的轮次验
- 严格的上游 Pi 工具参数验
- 连续角色的轮次
- 严格的上游 Pi 工具参数
### Google/Gemini
- 插件所属的工具 schema 清理
- 插件拥有的工具 schema 清理
### OpenAI
- 面向 Codex 模型的 `apply_patch` 工具
- Thinking Level 降级处理
- 思考等级降级处理
## TUI 集成
OpenClaw 还提供一种本地 TUI 模式,可直接使用 pi-tui 组件:
OpenClaw 还提供本地 TUI 模式,可直接使用 pi-tui 组件:
```typescript
// src/tui/tui.ts
@ -522,27 +522,27 @@ import { ... } from "@mariozechner/pi-tui";
这提供了与 pi 原生模式类似的交互式终端体验。
## 与 Pi CLI 的关键差异
## 与 Pi CLI 的主要差异
| 方面 | Pi CLI | OpenClaw 内嵌式 |
| 方面 | Pi CLI | OpenClaw 内嵌式 |
| --------------- | ----------------------- | ---------------------------------------------------------------------------------------------- |
| 调用方式 | `pi` 命令 / RPC | 通过 `createAgentSession()` 使用 SDK |
| 工具 | 默认编码工具 | 自定义 OpenClaw 工具套件 |
| 系统提示词 | AGENTS.md + prompts | 按渠道/上下文动态生成 |
| 会话存储 | `~/.pi/agent/sessions/` | `~/.openclaw/agents/<agentId>/sessions/`(或 `$OPENCLAW_STATE_DIR/agents/<agentId>/sessions/` |
| 认证 | 单一凭证 | 支持轮换的多配置 |
| 扩展 | 从磁盘加载 | 通过编程方式 + 磁盘路径 |
| 扩展 | 从磁盘加载 | 通过编程方式 + 磁盘路径加载 |
| 事件处理 | TUI 渲染 | 基于回调(`onBlockReply` 等) |
## 未来考虑
## 后续考虑
潜在需要重构的领域
可能需要重构的方向
1. **工具签名对齐**:当前仍在适配 pi-agent-core 与 pi-coding-agent 之间的签名差异
2. **Session manager 包装**`guardSessionManager` 增加了安全性,但也提升了复杂度
1. **工具签名对齐**:当前需要在 pi-agent-core 和 pi-coding-agent 的签名之间做适配
2. **SessionManager 封装**`guardSessionManager` 增加了安全性,但也提升了复杂度
3. **扩展加载**:可以更直接地使用 pi 的 `ResourceLoader`
4. **流式处理器复杂度**`subscribeEmbeddedPiSession` 已变得较大
5. **提供商特殊处理**:存在许多提供商特定代码路径,而这些逻辑未来可能由 pi 来统一处理
5. **提供商特殊行为**:存在许多提供商特定代码路径,这些理论上可能由 pi 来处理
## 测试
@ -564,9 +564,9 @@ Pi 集成覆盖以下测试套件:
- `src/agents/pi-embedded-runner-extraparams.live.test.ts`(启用 `OPENCLAW_LIVE_TEST=1`
当前运行命令请参见 [Pi 开发工作流](/zh-CN/pi-dev)。
当前运行命令请参见 [Pi Development Workflow](/zh-CN/pi-dev)。
## 相关内容
- [Pi 开发工作流](/zh-CN/pi-dev)
- [安装概览](/zh-CN/install)
- [Pi development workflow](/zh-CN/pi-dev)
- [Install overview](/zh-CN/install)

View File

@ -1,97 +1,97 @@
---
read_when:
- 实现提供商运行时钩子、渠道生命周期或软件包打包集合
- 实现提供商运行时钩子、渠道生命周期或软件包打包
- 调试插件加载顺序或注册表状态
- 添加新的插件能力或上下文引擎插件
summary: 插件架构内部机制加载流水线、注册表、运行时钩子、HTTP 路由和参考表格
title: 插件架构内部机制
x-i18n:
generated_at: "2026-04-24T16:05:39Z"
generated_at: "2026-04-24T16:35:16Z"
model: gpt-5.4
provider: openai
source_hash: 19018f885f2a8a5f49d5603e122f8b6c7053e28a27a5ac3a4fd315d2cf9be2ac
source_hash: 123f9228a70bda44cc2852933383b19214563c557d2c4dff1ad17585acfeb551
source_path: plugins/architecture-internals.md
workflow: 15
---
关于公开的能力模型、插件形态以及所有权 / 执行契约,请参阅 [Plugin architecture](/zh-CN/plugins/architecture)。本页是内部机制的参考文档加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。
关于公共能力模型、插件形态以及所有权 / 执行契约,请参阅 [插件架构](/zh-CN/plugins/architecture)。本页是内部机制的参考文档加载流水线、注册表、运行时钩子、Gateway 网关 HTTP 路由、导入路径和模式表。
## 加载流水线
在启动时OpenClaw 大致会执行以下流程
启动时OpenClaw 大致会这样做
1. 发现候选插件根目录
2. 读取原生或兼容 bundle 清单以及软件包元数据
3. 拒绝不安全的候选项
4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、 `slots`、`load.paths`
5. 决定每个候选项是否启用
4. 规范化插件配置(`plugins.enabled`、`allow`、`deny`、`entries`、`slots`、`load.paths`
5. 为每个候选项决定是否启用
6. 加载已启用的原生模块:已构建的内置模块使用原生加载器;未构建的原生插件使用 `jiti`
7. 调用原生 `register(api)` 钩子,并将注册内容收集到插件注册表中
8. 将注册表暴露给命令 / 运行时表面
<Note>
`activate``register` 的旧别名——加载器会解析存在的那个(`def.register ?? def.activate`),并在相同的时机调用它。所有内置插件都使用 `register`;新插件请优先使用 `register`
`activate``register` 的旧别名——加载器会解析两者中存在的那个(`def.register ?? def.activate`),并在相同阶段调用它。所有内置插件都使用 `register`;新插件请优先使用 `register`
</Note>
安全门禁会在运行时执行**之前**发生。当入口逃逸出插件根目录、路径对所有用户可写,或对于非内置插件路径所有权看起来可疑时,候选项会被阻止。
安全门禁发生在运行时执行**之前**。当入口路径逃逸出插件根目录、路径对所有用户可写,或对于非内置插件而言路径所有权看起来可疑时,候选项会被阻止。
### 清单优先行为
清单是控制平面的真实来源。OpenClaw 用它来:
清单是控制平面的事实来源。OpenClaw 使用它来:
- 标识插件
- 发现声明的渠道 / Skills / 配置模式或 bundle 能力
- 验证 `plugins.entries.<id>.config`
- 增强控制 UI 的标签 / 占位符
- 显示安装 / 目录元数据
- 在不加载插件运行时的情况下,保留轻量级激活和设置描述符
- 在不加载插件运行时的前提下保留轻量的激活和设置描述符
对于原生插件,运行时模块是数据平面部分。它会注册实际行为,例如钩子、工具、命令或提供商流程。
可选的清单 `activation``setup` 块仍然留在控制平面。它们只是用于激活规划和设置发现的元数据描述符;它们不会替代运行时注册、`register(...)` 或 `setupEntry`
首批实时激活使用方现在会使用清单中的命令、渠道和提供商提示,在更广泛的注册表物化之前缩小插件加载范围:
可选的清单 `activation``setup` 块仍然留在控制平面。它们只是用于激活规划和设置发现的元数据描述符;它们不会替代运行时注册、`register(...)` 或 `setupEntry`
首批实时激活使用方现在会使用清单中的命令、渠道和提供商提示,在更广泛的注册表实体化之前先缩小插件加载范围:
- CLI 加载会缩小到拥有所请求主命令的插件
- 渠道设置 / 插件解析会缩小到拥有所请求渠道 id 的插件
- 显式提供商设置 / 运行时解析会缩小到拥有所请求提供商 id 的插件
激活规划器既为现有调用方提供仅包含 id 的 API也为新的诊断场景提供计划 API。计划条目会报告插件为何被选中并将显式 `activation.*` 规划器提示与清单所有权回退区分开来,例如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和钩子。这个原因拆分是兼容性边界:现有插件元数据仍可正常工作,而新代码可以在不改变运行时加载语义的前提下检测宽泛提示或回退行为
激活规划器同时暴露了供现有调用方使用的仅含 id 的 API以及供新诊断功能使用的 plan API。Plan 条目会报告插件为何被选中,将显式的 `activation.*` 规划器提示与清单所有权回退(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks区分开来。这个原因拆分就是兼容性边界现有插件元数据可以继续工作而新代码可以检测宽泛提示或回退行为而无需改变运行时加载语义
设置发现现在会优先使用描述符拥有的 id例如 `setup.providers``setup.cliBackends`,以在回退到 `setup-api` 之前缩小候选插件范围;`setup-api` 用于那些仍然需要设置期运行时钩子的插件。如果发现的多个插件声称拥有同一个规范化设置提供商或 CLI 后端 id设置查找会拒绝这个有歧义的所有者,而不是依赖发现顺序。
设置发现现在会优先使用由描述符拥有的 id`setup.providers``setup.cliBackends`)来缩小候选插件范围,然后才会回退到 `setup-api`,以兼容那些仍然需要设置时运行时钩子的插件。如果多个已发现的插件声明了相同的规范化设置提供商或 CLI 后端 id设置查找会拒绝这个有歧义的所有者,而不是依赖发现顺序。
### 加载器会缓存什么
OpenClaw 会为以下内容保留短期的进程内缓存:
OpenClaw 会为以下内容保留短生命周期的进程内缓存:
- 发现结果
- 清单注册表数据
- 已加载的插件注册表
这些缓存可减少突发启动和重复命令带来的开销。可以把它们安全地理解为短生命周期的性能缓存,而不是持久化存储。
这些缓存可减少突发启动和重复命令带来的开销。可以安全地将它们视为短期性能缓存,而不是持久化存储。
性能说明:
- 设置 `OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE=1``OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE=1` 可禁用这些缓存。
- 使用 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS``OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存时间窗口。
- 可通过 `OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS``OPENCLAW_PLUGIN_MANIFEST_CACHE_MS` 调整缓存窗口。
## 注册表模型
已加载的插件不会直接随意修改核心的全局状态。它们会注册到一个中央插件注册表中。
已加载的插件不会直接修改任意核心全局状态。它们会注册到一个中心化的插件注册表中。
注册表会跟踪:
- 插件记录(标识、来源、起源、状态、诊断信息
- 插件记录(身份、来源、源头、状态、诊断
- 工具
- 旧版钩子和类型化钩子
- 渠道
- 提供商
- Gateway 网关 RPC 处理器
- gateway RPC 处理器
- HTTP 路由
- CLI 注册器
- 后台服务
- 插件拥有的命令
随后,核心功能会从该注册表读取,而不是直接与插件模块交互。这样可以让加载保持单向:
然后,核心功能会从该注册表中读取,而不是直接与插件模块通信。这样可使加载保持单向:
- 插件模块 -> 注册表注册
- 核心运行时 -> 注册表消费
@ -100,9 +100,9 @@ OpenClaw 会为以下内容保留短期的进程内缓存:
## 会话绑定回调
绑定会话的插件可以在批结果确定后作出响应。
绑定会话的插件可以在批结果确定后作出响应。
使用 `api.onConversationBindingResolved(...)`在绑定请求被批准或拒绝后接收回调:
使用 `api.onConversationBindingResolved(...)`在绑定请求被批准或拒绝后接收回调:
```ts
export default {
@ -110,12 +110,12 @@ export default {
register(api) {
api.onConversationBindingResolved(async (event) => {
if (event.status === "approved") {
// 现在已存在此插件 + 会话的绑定。
// A binding now exists for this plugin + conversation.
console.log(event.binding?.conversationId);
return;
}
// 请求被拒绝;清除任何本地待处理状态。
// The request was denied; clear any local pending state.
console.log(event.request.conversation.conversationId);
});
},
@ -126,82 +126,82 @@ export default {
- `status``"approved"` 或 `"denied"`
- `decision``"allow-once"`、`"allow-always"` 或 `"deny"`
- `binding`:已批准请求的解析绑定
- `request`:原始请求摘要、detach 提示、发送方 id 和会话元数据
- `binding`:已批准请求的解析绑定
- `request`:原始请求摘要、分离提示、发送者 id 和会话元数据
此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在核心批处理完成后运行。
此回调仅用于通知。它不会改变谁被允许绑定会话,并且会在核心批处理完成后运行。
## 提供商运行时钩子
提供商插件分为三层:
提供商插件三层:
- **清单元数据**用于低成本运行前查找:`providerAuthEnvVars`、 `providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`
- **配置期钩子**`catalog`(旧称 `discovery`)以及 `applyConfigDefaults`
- **运行时钩子**40 多个可选钩子,涵盖认证、模型解析、流包装、思考级别、重放策略和使用情况端点。完整列表请参见 [钩子顺序和用法](#hook-order-and-usage)。
- 用于低成本运行前查找的**清单元数据**`providerAuthEnvVars`、`providerAuthAliases`、`providerAuthChoices` 和 `channelEnvVars`
- **配置时钩子**`catalog`(旧版 `discovery`)以及 `applyConfigDefaults`
- **运行时钩子**40 多个可选钩子,覆盖凭证、模型解析、流包装、思考级别、重放策略和用量端点。完整列表见 [钩子顺序与用法](#hook-order-and-usage)。
OpenClaw 仍然负责通用的智能体循环、故障转移、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,因此无需实现整套自定义推理传输。
OpenClaw 仍然负责通用的智能体循环、故障切换、转录处理和工具策略。这些钩子是提供商特定行为的扩展表面,无需为此实现整套自定义推理传输。
当提供商具有基于环境变量的凭证,并且通用认证 / 状态 / 模型选择器路径需要在不加载插件运行时的情况下看到这些凭证时,请使用清单 `providerAuthEnvVars`。当一个提供商 id 需要复用另一个提供商 id 的环境变量、认证配置文件、基于配置的认证以及 API 密钥新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导 / 认证选项 CLI 表面需要在不加载提供商运行时的情况下知道提供商的 choice id、分组标签和简单的单标志认证接线时请使用清单 `providerAuthChoices`。保留提供商运行时 `envVars` 用于面向运维人员的提示,例如新手引导标签或 OAuth client-id / client-secret 设置变量。
当提供商使用基于环境变量的凭证,并且通用凭证 / 状态 / 模型选择器路径需要在不加载插件运行时的情况下感知这些凭证时,请使用清单 `providerAuthEnvVars`。当某个提供商 id 需要复用另一个提供商 id 的环境变量、凭证配置文件、配置支持的凭证和 API 密钥新手引导选项时,请使用清单 `providerAuthAliases`。当新手引导 / 凭证选择 CLI 表面需要在不加载提供商运行时的情况下了解该提供商的 choice id、分组标签和简单的单标志凭证接线时请使用清单 `providerAuthChoices`。提供商运行时中的 `envVars` 应保留给面向运维人员的提示,例如新手引导标签或 OAuth client-id / client-secret 设置变量。
当某个渠道具有由环境变量驱动的证或设置,并且通用 shell 环境变量回退、配置 / 状态检查或设置提示需要在不加载渠道运行时的情况下看到这些内容时,请使用清单 `channelEnvVars`
当某个渠道具有由环境变量驱动的证或设置,并且通用 shell 环境变量回退、配置 / 状态检查或设置提示需要在不加载渠道运行时的情况下感知它们时,请使用清单 `channelEnvVars`
### 钩子顺序用法
### 钩子顺序用法
对于模型 / 提供商插件OpenClaw 大致会按以下顺序调用钩子。
对于模型 / 提供商插件OpenClaw 会按大致如下顺序调用钩子。
“何时使用”列是快速决策指南。
| # | 钩子 | 作用 | 何时使用 |
| --- | --------------------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers` | 提供商拥有目录或基础 URL 默认值 |
| 2 | `applyConfigDefaults` | 在配置物化期间应用由提供商拥有的全局配置默认值 | 默认值依赖于认证模式、环境变量或提供商模型族语义 |
| -- | _(内置模型查找)_ | OpenClaw 会先尝试常规注册表 / 目录路径 | _(不是插件钩子)_ |
| 3 | `normalizeModelId` | 在查找前规范化旧版或预览版 model-id 别名 | 提供商拥有在规范模型解析前进行别名清理的逻辑 |
| 4 | `normalizeTransport` | 在通用模型组装规范化提供商族的 `api` / `baseUrl` | 提供商拥有同一传输族中自定义提供商 id 的传输清理逻辑 |
| 5 | `normalizeConfig` | 在运行时 / 提供商解析前规范化 `models.providers.<id>` | 提供商需要应随插件存在的配置清理;内置的 Google 系列辅助逻辑也会为受支持的 Google 配置条目提供兜底 |
| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式使用情况兼容性重写 | 提供商需要基于端点的原生流式使用情况元数据修复 |
| 7 | `resolveConfigApiKey` | 在加载运行时认证之前,为配置提供商解析 env-marker 认证 | 提供商拥有自己的 env-marker API 密钥解析`amazon-bedrock` 在这里也有一个内置的 AWS env-marker 解析器 |
| 8 | `resolveSyntheticAuth` | 在不持久化明文的前提下暴露本地 / 自托管或基于配置的认证 | 提供商可使用合成 / 本地凭证标记运行 |
| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部证配置文件CLI / 应用拥有的凭证默认 `persistence``runtime-only` | 提供商复用外部认证凭证而不持久化复制的刷新令牌;请在清单中声明 `contracts.externalAuthProviders` |
| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的合成配置文件占位符降级到环境变量 / 基于配置的认证之后 | 提供商会存储合成占位符配置文件,而这些配置文件不应具有更高优先级 |
| 11 | `resolveDynamicModel` | 对本地注册表中尚不存在的提供商拥有的模型 id 进行同步回退解析 | 提供商接受任意上游模型 id |
| 12 | `prepareDynamicModel` | 异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 |
| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用解析后的模型之前进行最终重写 | 提供商需要进行传输重写,但仍使用核心传输 |
| 14 | `contributeResolvedModelCompat` | 为位于另一兼容传输之后的供应商模型提供兼容性标志 | 提供商能够在代理传输上识别自己的模型,而无需接管该提供商 |
| 15 | `capabilities` | 由共享核心逻辑使用的提供商拥有的转录 / 工具元数据 | 提供商需要处理转录 / 提供商族特殊行为 |
| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式之前对其进行规范化 | 提供商需要传输族级别的模式清理 |
| 17 | `inspectToolSchemas` | 在规范化之后暴露由提供商拥有的模式诊断信息 | 提供商希望提供关键字警告,而不需要让核心了解提供商特定规则 |
| 18 | `resolveReasoningOutputMode` | 选择原生推理输出契约还是带标签的推理输出契约 | 提供商需要带标签的推理 / 最终输出,而不是原生字段 |
| 19 | `prepareExtraParams` | 在通用流选项包装器之前进行请求参数规范化 | 提供商需要默认请求参数或按提供商区分的参数清理 |
| 20 | `createStreamFn` | 使用自定义传输完全替换常规流路径 | 提供商需要自定义线路协议,而不仅仅是一个包装器 |
| 21 | `wrapStreamFn` | 在应用通用包装器后对流函数进行包装 | 提供商需要请求头 / 请求体 / 模型兼容性包装,而不是自定义传输 |
| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输头或元数据 | 提供商希望通用传输发送提供商原生的轮次标识 |
| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 头或会话冷却策略 | 提供商希望通用 WS 传输能够调整会话头或回退策略 |
| 24 | `formatApiKey` | 认证配置文件格式化器:已存储的配置文件变为运行时 `apiKey` 字符串 | 提供商存储额外的认证元数据,并需要自定义的运行时令牌形态 |
| 25 | `refreshOAuth` | 针对自定义刷新端点或刷新失败策略的 OAuth 刷新重写 | 提供商不适配共享的 `pi-ai` 刷新器 |
| 26 | `buildAuthDoctorHint` | 当 OAuth 刷新失败时附加的修复提示 | 提供商在刷新失败后需要由提供商拥有的认证修复指导 |
| 27 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法识别的原始溢出错误 |
| 28 | `classifyFailoverReason` | 由提供商拥有的故障转移原因分类 | 提供商可以将原始 API / 传输错误映射为限流 / 过载等 |
| 29 | `isCacheTtlEligible` | 适用于代理 / 回程提供商的提示缓存策略 | 提供商需要代理特定的缓存 TTL 门控 |
| 30 | `buildMissingAuthMessage` | 替代通用缺失认证恢复消息 | 提供商需要提供商特定的缺失认证恢复提示 |
| 31 | `suppressBuiltInModel` | 过时上游模型抑制,以及可选的面向用户错误提示 | 提供商需要隐藏过时的上游条目,或用供应商提示替代它们 |
| 32 | `augmentModelCatalog` | 在发现之后追加合成 / 最终目录条目 | 提供商需要在 `models list` 和选择器中提供合成的前向兼容条目 |
| 33 | `resolveThinkingProfile` | 针对特定模型的 `/think` 级别集合、显示标签和默认值 | 提供商为选定模型暴露自定义思考层级或二元标签 |
| 34 | `isBinaryThinking` | 开 / 关推理切换兼容性钩子 | 提供商仅暴露二元的思考开 / 关 |
| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商希望在部分模型上启用 `xhigh` |
| 36 | `resolveDefaultThinkingLevel` | 默认 `/think`兼容性钩子 | 提供商拥有某个模型族的默认 `/think` 策略 |
| 37 | `isModernModelRef` | 用于实时配置文件过滤和 smoke 选择的现代模型匹配器 | 提供商拥有实时 / smoke 首选模型匹配逻辑 |
| 38 | `prepareRuntimeAuth` | 在推理之前,将已配置的凭证交换为实际运行时令牌 / 密钥 | 提供商需要令牌交换或短生命周期的请求凭证 |
| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析使用情况 / 计费凭证 | 提供商需要自定义使用情况 / 配额令牌解析,或使用不同的使用情况凭证 |
| 40 | `fetchUsageSnapshot` | 在认证解析完成后获取并规范化提供商特定的使用情况 / 配额快照 | 提供商需要提供商特定的使用情况端点或负载解析器 |
| 41 | `createEmbeddingProvider` | 为内存 / 搜索构建由提供商拥有的嵌入适配器 | Memory 嵌入行为应归属于提供商插件 |
| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该提供商的转录处理 | 提供商需要自定义转录策略(例如,移除思考块) |
| 43 | `sanitizeReplayHistory` | 在通用转录清理之后重写重放历史 | 提供商需要超出共享压缩辅助工具范围的提供商特定重放重写 |
| 44 | `validateReplayTurns` | 在嵌入式运行器之前对重放轮次进行最终验证或重塑 | 提供商传输在通用净化之后需要更严格的轮次验证 |
| 45 | `onModelSelected` | 运行由提供商拥有的模型选定后副作用 | 当模型变为活动状态时,提供商需要遥测或由提供商拥有的状态 |
| # | 钩子 | 作用 | 何时使用 |
| --- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | `catalog` | 在生成 `models.json` 期间,将提供商配置发布到 `models.providers`| 提供商拥有目录或 base URL 默认值 |
| 2 | `applyConfigDefaults` | 在配置实体化期间应用由提供商拥有的全局配置默认值 | 默认值依赖于凭证模式、环境变量或提供商模型族语义 |
| -- | _(内置模型查找)_ | OpenClaw 会先尝试常规注册表 / 目录路径 | _(不是插件钩子)_ |
| 3 | `normalizeModelId` | 在查找前规范化旧版或预览版 model-id 别名 | 提供商拥有在规范模型解析前进行别名清理的逻辑 |
| 4 | `normalizeTransport` | 在通用模型组装前规范化提供商族的 `api` / `baseUrl` | 提供商拥有同一传输族中自定义提供商 id 的传输清理逻辑 |
| 5 | `normalizeConfig` | 在运行时 / 提供商解析前规范化 `models.providers.<id>` | 提供商需要将配置清理逻辑保留在插件中;内置的 Google 族辅助逻辑也会为受支持的 Google 配置条目提供兜底 |
| 6 | `applyNativeStreamingUsageCompat` | 对配置提供商应用原生流式用量兼容性重写 | 提供商需要基于端点驱动的原生流式用量元数据修复 |
| 7 | `resolveConfigApiKey` | 在加载运行时凭证前,为配置提供商解析 env-marker 凭证 | 提供商拥有自己的 env-marker API key 解析逻辑`amazon-bedrock` 在这里也有一个内置的 AWS env-marker 解析器 |
| 8 | `resolveSyntheticAuth` | 在不持久化明文的情况下暴露本地 / 自托管或配置支持的凭证 | 提供商可以使用 synthetic / 本地凭证标记运行 |
| 9 | `resolveExternalAuthProfiles` | 叠加由提供商拥有的外部证配置文件CLI / 应用拥有的凭证默认 `persistence``runtime-only` | 提供商复用外部凭证而不持久化复制的 refresh token;请在清单中声明 `contracts.externalAuthProviders` |
| 10 | `shouldDeferSyntheticProfileAuth` | 将已存储的 synthetic 配置文件占位符降低到 env / 配置支持凭证之后 | 提供商会存储 synthetic 占位配置文件,而这些占位符不应获得优先级 |
| 11 | `resolveDynamicModel` | 为尚未存在于本地注册表中的、由提供商拥有的模型 id 提供同步回退 | 提供商接受任意上游模型 id |
| 12 | `prepareDynamicModel` | 先执行异步预热,然后再次运行 `resolveDynamicModel` | 提供商在解析未知 id 之前需要网络元数据 |
| 13 | `normalizeResolvedModel` | 在嵌入式运行器使用解析模型之前进行最终重写 | 提供商需要传输重写,但仍使用核心传输 |
| 14 | `contributeResolvedModelCompat` | 为位于另一种兼容传输之后的厂商模型提供兼容标记 | 提供商可在不接管该提供商的前提下识别代理传输上的自有模型 |
| 15 | `capabilities` | 由共享核心逻辑使用的、由提供商拥有的转录 / 工具元数据 | 提供商需要处理转录 / 提供商族特殊行为 |
| 16 | `normalizeToolSchemas` | 在嵌入式运行器看到工具模式之前规范化它们 | 提供商需要传输族模式清理 |
| 17 | `inspectToolSchemas` | 在规范化之后暴露由提供商拥有的模式诊断信息 | 提供商希望给出关键字警告,而无需让核心理解提供商特定规则 |
| 18 | `resolveReasoningOutputMode` | 选择原生还是带标签的推理输出契约 | 提供商需要使用带标签的推理 / 最终输出,而不是原生字段 |
| 19 | `prepareExtraParams` | 在通用流选项包装器之前执行请求参数规范化 | 提供商需要默认请求参数或按提供商清理参数 |
| 20 | `createStreamFn` | 用自定义传输完全替换常规流路径 | 提供商需要自定义线协议,而不只是一个包装器 |
| 21 | `wrapStreamFn` | 在应用通用包装器后对流函数进行包装 | 提供商需要请求头 / 请求体 / 模型兼容性包装器,但不需要自定义传输 |
| 22 | `resolveTransportTurnState` | 附加原生的逐轮传输请求头或元数据 | 提供商希望通用传输发送提供商原生的轮次身份信息 |
| 23 | `resolveWebSocketSessionPolicy` | 附加原生 WebSocket 请求头或会话冷却策略 | 提供商希望通用 WS 传输调整会话请求头或回退策略 |
| 24 | `formatApiKey` | 凭证配置文件格式化器:已存储的配置文件会变成运行时 `apiKey` 字符串 | 提供商存储额外凭证元数据,并需要自定义运行时 token 形态 |
| 25 | `refreshOAuth` | 为自定义刷新端点或刷新失败策略覆盖 OAuth 刷新逻辑 | 提供商不适配共享的 `pi-ai` 刷新器 |
| 26 | `buildAuthDoctorHint` | 在 OAuth 刷新失败时附加修复提示 | 提供商在刷新失败后需要由提供商拥有的凭证修复指引 |
| 27 | `matchesContextOverflowError` | 由提供商拥有的上下文窗口溢出匹配器 | 提供商存在通用启发式无法识别的原始溢出错误 |
| 28 | `classifyFailoverReason` | 由提供商拥有的故障切换原因分类 | 提供商可以将原始 API / 传输错误映射为限流 / 过载等原因 |
| 29 | `isCacheTtlEligible` | 面向代理 / 回传提供商的提示缓存策略 | 提供商需要代理特定的缓存 TTL 门控 |
| 30 | `buildMissingAuthMessage` | 替换通用的缺失凭证恢复消息 | 提供商需要提供商特定的缺失凭证恢复提示 |
| 31 | `suppressBuiltInModel` | 过时上游模型抑制,并可选提供面向用户的错误提示 | 提供商需要隐藏过时的上游条目,或用厂商提示替换它们 |
| 32 | `augmentModelCatalog` | 在发现后追加 synthetic / 最终目录条目 | 提供商需要在 `models list` 和选择器中添加 synthetic 前向兼容条目 |
| 33 | `resolveThinkingProfile` | 特定模型的 `/think` 等级集合、显示标签和默认值 | 提供商为选定模型暴露自定义思考阶梯或二元标签 |
| 34 | `isBinaryThinking` | 开 / 关推理切换兼容性钩子 | 提供商只暴露二元的思考开 / 关 |
| 35 | `supportsXHighThinking` | `xhigh` 推理支持兼容性钩子 | 提供商希望在部分模型上启用 `xhigh` |
| 36 | `resolveDefaultThinkingLevel` | 默认 `/think` 级兼容性钩子 | 提供商拥有某个模型族的默认 `/think` 策略 |
| 37 | `isModernModelRef` | 用于实时配置文件筛选和 smoke 选择的现代模型匹配器 | 提供商拥有实时 / smoke 首选模型匹配逻辑 |
| 38 | `prepareRuntimeAuth` | 在推理前一刻,将已配置的凭证交换为实际运行时 token / key | 提供商需要 token 交换或短生命周期请求凭证 |
| 39 | `resolveUsageAuth` | 为 `/usage` 及相关状态表面解析用量 / 计费凭证 | 提供商需要自定义用量 / 配额 token 解析,或需要不同的用量凭证 |
| 40 | `fetchUsageSnapshot` | 在凭证解析完成后,抓取并规范化提供商特定的用量 / 配额快照 | 提供商需要提供商特定的用量端点或负载解析器 |
| 41 | `createEmbeddingProvider` | 为 memory / 搜索构建由提供商拥有的嵌入适配器 | Memory 嵌入行为应归属于提供商插件 |
| 42 | `buildReplayPolicy` | 返回一个重放策略,用于控制该提供商的转录处理 | 提供商需要自定义转录策略(例如剥离思考块) |
| 43 | `sanitizeReplayHistory` | 在通用转录清理之后重写重放历史 | 提供商需要超出共享压缩辅助工具之外的提供商特定重放重写 |
| 44 | `validateReplayTurns` | 在嵌入式运行器之前,对重放轮次做最终验证或重塑 | 提供商传输在通用净化后需要更严格的轮次验证 |
| 45 | `onModelSelected` | 在模型被选中后运行由提供商拥有的副作用 | 当模型激活时,提供商需要遥测或由提供商拥有的状态 |
`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的提供商插件,然后继续检查其他具备钩子能力的提供商插件,直到某个插件实际更改了模型 id 或传输 / 配置。这样可以让别名 / 兼容性提供商 shim 继续工作,而无需调用方知道哪个内置插件拥有该重写逻辑。如果没有任何提供商钩子重写受支持的 Google 系列配置条目,内置的 Google 配置规范化器仍会应用该兼容性清理。
`normalizeModelId`、`normalizeTransport` 和 `normalizeConfig` 会先检查已匹配的提供商插件,然后继续尝试其他具备对应钩子能力的提供商插件,直到某个插件实际更改了模型 id 或传输 / 配置为止。这让别名 / 兼容性提供商 shim 能够继续工作,而无需调用方知道到底是哪个内置插件拥有该重写逻辑。如果没有任何提供商钩子重写受支持的 Google 配置条目,内置的 Google 配置规范化器仍会应用该兼容性清理。
如果提供商需要完全自定义的线协议或自定义请求执行器,那是另一类扩展。这些钩子适用于仍在 OpenClaw 常规推理循环上运行的提供商行为。
如果提供商需要完全自定义的线协议或自定义请求执行器,那是另一类扩展。这些钩子适用于仍运行在 OpenClaw 常规推理循环上的提供商行为。
### 提供商示例
@ -259,39 +259,40 @@ api.registerProvider({
### 内置示例
内置提供商插件会组合使用上述钩子,以适配各供应商在目录、认证、思考、重放和使用情况方面的需求。权威钩子集合位于各插件在 `extensions/` 下的实现中;本页用于说明这些形态,而不是镜像整份列表。
内置提供商插件会组合使用上述钩子,以适配各厂商在目录、凭证、思考、重放和用量方面的需求。权威的钩子集合与各插件一同保存在 `extensions/` 下;本页旨在展示这些形态,而不是镜像整份列表。
<AccordionGroup>
<Accordion title="直通目录提供商">
OpenRouter、Kilocode、Z.AI、xAI 注册 `catalog` 以及
`resolveDynamicModel` / `prepareDynamicModel`从而能在 OpenClaw 的静态目录之前暴露上游模型 id。
<Accordion title="透传目录提供商">
OpenRouter、Kilocode、Z.AI、xAI 注册 `catalog` 以及
`resolveDynamicModel` / `prepareDynamicModel`这样它们就能在 OpenClaw 的静态目录之前暴露上游模型 id。
</Accordion>
<Accordion title="OAuth 和使用情况端点提供商">
GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 会将
`prepareRuntimeAuth``formatApiKey` `resolveUsageAuth` +
`fetchUsageSnapshot` 配合使用,以接管令牌交换和 `/usage` 集成。
<Accordion title="OAuth 和用量端点提供商">
GitHub Copilot、Gemini CLI、ChatGPT Codex、MiniMax、Xiaomi、z.ai 通过
`prepareRuntimeAuth``formatApiKey` 搭配 `resolveUsageAuth` +
`fetchUsageSnapshot` 来接管 token 交换和 `/usage` 集成。
</Accordion>
<Accordion title="重放和转录清理系列">
共享命名系列`google-gemini`、`passthrough-gemini`、
`anthropic-by-model`、`hybrid-anthropic-openai`让提供商能够通过
`buildReplayPolicy` 选择加入转录策略,而不必让每个插件都重新实现清理逻辑。
<Accordion title="重放和转录清理">
共享命名`google-gemini`、`passthrough-gemini`、
`anthropic-by-model`、`hybrid-anthropic-openai`允许提供商通过
`buildReplayPolicy` 选择启用转录策略,而不是让每个插件各自重新实现清理逻辑。
</Accordion>
<Accordion title="仅目录提供商">
`byteplus`、`cloudflare-ai-gateway`、`huggingface`、`kimi-coding`、`nvidia`、
`qianfan`、`synthetic`、`together`、`venice`、`vercel-ai-gateway` 和
`volcengine` 只注册 `catalog`,并使用共享推理循环。
`volcengine` 只注册 `catalog`,并用共享推理循环。
</Accordion>
<Accordion title="Anthropic 专用流辅助工具">
Beta headers、`/fast` / `serviceTier` `context1m` 位于
Anthropic 插件的公共 `api.ts` / `contract-api.ts` 接缝中
<Accordion title="Anthropic 特定流辅助工具">
Beta 请求头、`/fast` / `serviceTier` 以及 `context1m` 位于
Anthropic 插件公开的 `api.ts` / `contract-api.ts` 接缝中
`wrapAnthropicProviderStream`、`resolveAnthropicBetas`、
`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是放在通用 SDK 中。
`resolveAnthropicFastMode`、`resolveAnthropicServiceTier`),而不是放在
通用 SDK 中。
</Accordion>
</AccordionGroup>
## 运行时辅助工具
插件可以通过 `api.runtime` 访问选定的核心辅助工具。对于 TTS
插件可以通过 `api.runtime` 访问选定的核心辅助工具。以 TTS 为例
```ts
const clip = await api.runtime.tts.textToSpeech({
@ -312,14 +313,14 @@ const voices = await api.runtime.tts.listVoices({
说明:
- `textToSpeech` 会返回用于文件 / 语音便签表面的常规核心 TTS 输出负载。
- `textToSpeech` 返回供文件 / 语音便笺表面使用的常规核心 TTS 输出负载。
- 使用核心 `messages.tts` 配置和提供商选择。
- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商执行重采样 / 编码。
- `listVoices` 对每个提供商而言是可选的。可将其用于供应商自有的语音选择器或设置流程。
- 语音列表可包含更丰富的元数据,例如区域设置、性别和个性标签,以供提供商感知型选择器使用
- 目前支持电话语音的有 OpenAI 和 ElevenLabs。Microsoft 不支持。
- 返回 PCM 音频缓冲区 + 采样率。插件必须为提供商重采样 / 编码。
- `listVoices` 对每个提供商而言是可选的。可将其用于由厂商拥有的语音选择器或设置流程。
- 语音列表可包含更丰富的元数据,例如区域设置、性别和个性标签,以支持提供商感知型选择器
- 当前支持电话语音的只有 OpenAI 和 ElevenLabs。Microsoft 不支持。
插件可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。
插件可以通过 `api.registerSpeechProvider(...)` 注册语音提供商。
```ts
api.registerSpeechProvider({
@ -340,11 +341,11 @@ api.registerSpeechProvider({
说明:
- 将 TTS 策略、回退和回复投递保留在核心中。
- 使用语音提供商来承载供应商自有的合成行为
- 对于由厂商拥有的合成行为,请使用语音提供商。
- 旧版 Microsoft `edge` 输入会被规范化为 `microsoft` 提供商 id。
- 首选的所有权模型是面向公司的:随着 OpenClaw 增加这些能力契约,一个供应商插件可以统一拥有文本、语音、图像以及未来的媒体提供商。
- 推荐的所有权模型是面向公司的:随着 OpenClaw 增加这些能力契约,一个厂商插件可以统一拥有文本、语音、图像以及未来的媒体提供商。
对于图像 / 音频 / 视频理解,插件会注册一个类型的媒体理解提供商,而不是通用的键 / 包:
对于图像 / 音频 / 视频理解,插件会注册一个类型的媒体理解提供商,而不是一个通用 key/value 包:
```ts
api.registerMediaUnderstandingProvider({
@ -359,11 +360,11 @@ api.registerMediaUnderstandingProvider({
说明:
- 将编排、回退、配置和渠道接线保留在核心中。
- 将供应商行为保留在提供商插件中。
- 增量扩展应保持类型化:新的可选方法、新的可选结果字段、新的可选能力。
- 将商行为保留在提供商插件中。
- 增量扩展应保持类型化:新增可选方法、新增可选结果字段、新增可选能力。
- 视频生成已经遵循同样的模式:
- 核心拥有能力契约和运行时辅助工具
- 供应商插件注册 `api.registerVideoGenerationProvider(...)`
- 商插件注册 `api.registerVideoGenerationProvider(...)`
- 功能 / 渠道插件消费 `api.runtime.videoGeneration.*`
对于媒体理解运行时辅助工具,插件可以调用:
@ -381,7 +382,7 @@ const video = await api.runtime.mediaUnderstanding.describeVideoFile({
});
```
对于音频转写,插件既可以使用媒体理解运行时,也可以使用旧版 STT 别名:
对于音频转录,插件既可以使用媒体理解运行时,也可以使用较旧的 STT 别名:
```ts
const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
@ -396,7 +397,7 @@ const { text } = await api.runtime.mediaUnderstanding.transcribeAudioFile({
- `api.runtime.mediaUnderstanding.*` 是图像 / 音频 / 视频理解的首选共享表面。
- 使用核心媒体理解音频配置(`tools.media.audio`)和提供商回退顺序。
- 当未产生转写输出时,会返回 `{ text: undefined }`(例如输入被跳过 / 不受支持)
- 当未产生转录输出时(例如输入被跳过 / 不受支持),返回 `{ text: undefined }`
- `api.runtime.stt.transcribeAudioFile(...)` 仍保留为兼容性别名。
插件还可以通过 `api.runtime.subagent` 启动后台子智能体运行:
@ -414,12 +415,12 @@ const result = await api.runtime.subagent.run({
说明:
- `provider``model` 是每次运行的可选覆盖项,而不是持久化的会话变更。
- OpenClaw 仅对受信任调用方认可这些覆盖字段。
- 对于插件自有的回退运行,运维人员必须通过 `plugins.entries.<id>.subagent.allowModelOverride: true` 显式启用。
- 使用 `plugins.entries.<id>.subagent.allowedModels` 将受信任插件限制为特定规范 `provider/model` 目标,或使用 `"*"` 明确允许任意目标。
- 不受信任插件的子智能体运行仍可工作,但覆盖请求会被拒绝,而不是静默回退。
- OpenClaw 只会为受信任的调用方接受这些覆盖字段。
- 对于由插件拥有的回退运行,运维人员必须通过 `plugins.entries.<id>.subagent.allowModelOverride: true` 显式启用。
- 使用 `plugins.entries.<id>.subagent.allowedModels` 可将受信任插件限制到特定的规范 `provider/model` 目标,或设置为 `"*"` 以显式允许任意目标。
- 非受信任插件的子智能体运行仍可正常工作,但覆盖请求会被拒绝,而不是静默回退。
对于 Web 搜索,插件可以消费共享运行时辅助工具,而不是深入依赖智能体工具接线:
对于 Web 搜索,插件可以消费共享运行时辅助工具,而不是深入 agent 工具接线:
```ts
const providers = api.runtime.webSearch.listProviders({
@ -435,14 +436,13 @@ const result = await api.runtime.webSearch.search({
});
```
插件也可以通过
`api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。
插件也可以通过 `api.registerWebSearchProvider(...)` 注册 Web 搜索提供商。
说明:
- 将提供商选择、凭证解析和共享请求语义保留在核心中。
- 使用 Web 搜索提供商来承载供应商特定的搜索传输
- `api.runtime.webSearch.*` 是功能 / 渠道插件的首选共享表面,可在不依赖智能体工具包装器的情况下使用搜索行为
- 对于厂商特定的搜索传输,请使用 Web 搜索提供商。
- 对于需要搜索行为但又不想依赖 agent 工具包装器的功能 / 渠道插件,`api.runtime.webSearch.*` 是首选共享表面
### `api.runtime.imageGeneration`
@ -480,168 +480,166 @@ api.registerHttpRoute({
路由字段:
- `path`Gateway 网关 HTTP 服务器下的路由路径。
- `auth`:必填。使用 `"gateway"` 以要求常规 Gateway 网关认证,或使用 `"plugin"` 进行插件自主管理的认证 / webhook 验证
- `auth`:必填。使用 `"gateway"` 以要求常规 Gateway 网关凭证,或使用 `"plugin"` 以启用由插件管理的凭证 / webhook 校验
- `match`:可选。可为 `"exact"`(默认)或 `"prefix"`
- `replaceExisting`:可选。允许同一插件替换其已存在的路由注册。
- `replaceExisting`:可选。允许同一个插件替换自己已有的路由注册。
- `handler`:当路由处理了请求时返回 `true`
说明:
- `api.registerHttpHandler(...)` 已移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`
- `api.registerHttpHandler(...)`移除,并会导致插件加载错误。请改用 `api.registerHttpRoute(...)`
- 插件路由必须显式声明 `auth`
- 精确的 `path + match` 冲突会被拒绝,除非设置了 `replaceExisting: true`,并且一个插件不能替换另一个插件的路由。
- 使用不同 `auth` 级别的重叠路由会被拒绝。仅在相同认证级别内保留 `exact` / `prefix` 的贯穿链。
- `auth: "plugin"` 路由**不会**自动获得运维人员运行时作用域。它们用于插件自主管理的 webhook / 签名验证,而不是特权 Gateway 网关辅助调用。
- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内运行,但该作用域是有意保守的:
- 共享密钥 bearer 证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` 也是如此
- 受信任的带身份 HTTP 模式(例如 `trusted-proxy` 或私有入口上的 `gateway.auth.mode = "none"`)仅会在显式存在该请求头时认可 `x-openclaw-scopes`
- 如果这些带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退 `operator.write`
- 实用规则:不要假设经过 gateway 认证的插件路由天然就是隐式管理员表面。如果你的路由需要仅管理员可用的行为,请要求使用带身份的认证模式,并记录显式 `x-openclaw-scopes` 请求头契约。
- 除非设置 `replaceExisting: true`,否则完全相同的 `path + match` 冲突会被拒绝,而且一个插件不能替换另一个插件的路由。
- 具有不同 `auth` 级别的重叠路由会被拒绝。请只在相同凭证级别内保留 `exact` / `prefix` 的贯穿链。
- `auth: "plugin"` 路由**不会**自动接收运维人员运行时作用域。它们用于由插件管理的 webhook / 签名校验,而不是特权 Gateway 网关辅助调用。
- `auth: "gateway"` 路由会在 Gateway 网关请求运行时作用域内运行,但该作用域是有意收紧的:
- 共享密钥 bearer 证(`gateway.auth.mode = "token"` / `"password"`)会将插件路由运行时作用域固定为 `operator.write`,即使调用方发送了 `x-openclaw-scopes` 也是如此
- 受信任、携带身份的 HTTP 模式(例如 `trusted-proxy`,或私有入口上的 `gateway.auth.mode = "none"`)仅在显式携带该请求头时才会尊重 `x-openclaw-scopes`
- 如果这些带身份的插件路由请求中缺少 `x-openclaw-scopes`,运行时作用域会回退 `operator.write`
- 实际规则:不要假设一个采用 gateway 凭证的插件路由就是隐式管理面。如果你的路由需要仅管理员可用的行为,请要求使用携带身份的凭证模式,并记录显式的 `x-openclaw-scopes` 请求头契约。
## 插件 SDK 导入路径
在编写新插件时,请使用窄的 SDK 子路径,而不是单体式的 `openclaw/plugin-sdk` 根 barrel。核心子路径如下
在编写新插件时,请使用窄的 SDK 子路径,而不是单体式的 `openclaw/plugin-sdk` 根 barrel。核心子路径包括
| 子路径 | 用途 |
| 子路径 | 用途 |
| ----------------------------------- | -------------------------------------------------- |
| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 |
| `openclaw/plugin-sdk/channel-core` | 渠道入口 / 构建辅助工具 |
| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 |
| `openclaw/plugin-sdk/plugin-entry` | 插件注册原语 |
| `openclaw/plugin-sdk/channel-core` | 渠道入口 / 构建辅助工具 |
| `openclaw/plugin-sdk/core` | 通用共享辅助工具和总括契约 |
| `openclaw/plugin-sdk/config-schema` | 根 `openclaw.json` Zod 模式(`OpenClawSchema` |
渠道插件可从一组窄接缝中进行选择——`channel-setup`、
渠道插件应从一组窄化接缝中选择——`channel-setup`、
`setup-runtime`、`setup-adapter-runtime`、`setup-tools`、`channel-pairing`、
`channel-contract`、`channel-feedback`、`channel-inbound`、`channel-lifecycle`、
`channel-reply-pipeline`、`command-auth`、`secret-input`、`webhook-ingress`、
`channel-targets``channel-actions`。审批行为应统一收敛到一个 `approvalCapability` 契约上,而不是分散混用在不相关的插件字段中。参见 [Channel Plugins](/zh-CN/plugins/sdk-channel-plugins)。
`channel-targets``channel-actions`。审批行为应统一到单一的 `approvalCapability` 契约上,而不要混用不相关插件字段。参见 [渠道插件](/zh-CN/plugins/sdk-channel-plugins)。
运行时和配置辅助工具位于对应的 `*-runtime` 子路径下
`approval-runtime`、`config-runtime`、`infra-runtime`、`agent-runtime`、
`lazy-runtime`、`directory-runtime`、`text-runtime`、`runtime-store` 等)。
<Info>
`openclaw/plugin-sdk/channel-runtime` 已弃用——它只是用于旧插件的兼容性 shim。
新代码应改为导入更窄的通用原语。
`openclaw/plugin-sdk/channel-runtime` 已弃用——这是为旧插件提供的兼容性 shim。新代码应改为导入更窄化的通用原语。
</Info>
仓库内部入口点(按每个内置插件软件包根目录划分):
仓库内部入口点(按每个内置插件软件包根目录划分):
- `index.js` — 内置插件入口
- `api.js` — 辅助工具 / 类型 barrel
- `runtime-api.js` — 仅运行时 barrel
- `setup-entry.js` — 设置插件入口
- `index.js` 内置插件入口
- `api.js` 辅助工具 / 类型 barrel
- `runtime-api.js` 仅运行时 barrel
- `setup-entry.js` 设置插件入口
外部插件应仅导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或其他插件中导入另一个插件软件包的 `src/*`
Facade 加载的入口点在存在活动运行时配置快照时会优先使用它,否则回退到磁盘上的已解析配置文件。
外部插件只能导入 `openclaw/plugin-sdk/*` 子路径。绝不要从核心或其他插件中导入另一个插件软件包的 `src/*`
Facade 加载的入口点在存在活动运行时配置快照时会优先使用它,否则回退到磁盘上的已解析配置文件。
诸如 `image-generation`、`media-understanding` 和 `speech` 这样的能力专用子路径之所以存在,是因为内置插件今天就在使用它们。它们并不自动意味着是长期冻结的外部契约——在依赖它们之前,请查看相应的 SDK 参考页面
`image-generation`、`media-understanding` 和 `speech` 这样的能力专用子路径之所以存在,是因为当前内置插件在使用它们。它们并不自动构成长期冻结的外部契约——在依赖这些路径之前,请查看相关的 SDK 参考页
## 消息工具模式
对于反应、已读和投票等非消息原语,插件应自行拥有渠道特定的 `describeMessageTool(...)` 模式扩展
对于反应、已读和投票等非消息原语,插件应拥有渠道特定的 `describeMessageTool(...)` 模式贡献
共享发送展示应使用通用 `MessagePresentation` 契约,而不是提供商原生的按钮、组件、块或卡片字段。
关于契约、回退规则、提供商映射以及插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。
有关契约、回退规则、提供商映射和插件作者检查清单,请参见 [Message Presentation](/zh-CN/plugins/message-presentation)。
具备发送能力的插件会通过消息能力声明自己可以渲染的内容:
具备发送能力的插件通过消息能力声明它们可以渲染的内容:
- `presentation` 用于语义化展示块(`text`、`context`、`divider`、`buttons`、`select`
- `delivery-pin` 用于置顶投递请求
- `presentation`:用于语义展示块(`text`、`context`、`divider`、`buttons`、`select`
- `delivery-pin`用于置顶投递请求
核心会决定是原生渲染该展示,还是将其降级为文本。
不要从通用消息工具中暴露提供商原生 UI 的逃逸口。
为旧版原生模式保留的已弃用 SDK 辅助工具仍会继续导出,以支持现有第三方插件,但新插件不应使用它们。
核心会决定是原生渲染该展示,还是将其降级为文本。不要从通用消息工具中暴露提供商原生 UI 的逃生舱口。
为旧版原生模式保留的已弃用 SDK 辅助工具仍会继续导出,以兼容现有第三方插件,但新插件不应再使用它们。
## 渠道目标解析
渠道插件应拥有渠道特定的目标语义。保持共享出站宿主通用化,并使用消息适配器表面来承载提供商规则:
渠道插件应拥有渠道特定的目标语义。共享出站主机应保持通用,并使用消息适配器表面处理提供商规则:
- `messaging.inferTargetChatType({ to })` 决定规范化目标在目录查找前应被视为 `direct`、`group` 还是 `channel`
- `messaging.targetResolver.looksLikeId(raw, normalized)` 告诉核心某个输入是否应跳过目录搜索,直接进入类似 id 的解析流程
- `messaging.targetResolver.resolveTarget(...)` 是核心在规范化后或目录未命中后需要最终由提供商拥有的解析时使用的插件回退
- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后负责构造提供商特定的会话路由。
- `messaging.inferTargetChatType({ to })` 用于在目录查找前决定规范化目标应被视为 `direct`、`group` 还是 `channel`
- `messaging.targetResolver.looksLikeId(raw, normalized)` 用于告知核心:某个输入是否应跳过目录搜索,直接进入类似 id 的解析。
- `messaging.targetResolver.resolveTarget(...)`插件侧回退路径,当核心在规范化后或目录未命中后需要最终的、由提供商拥有的解析时使用。
- `messaging.resolveOutboundSessionRoute(...)` 在目标解析完成后负责提供商特定的会话路由构造
推荐拆分方式:
- 对于应在搜索联系人 / 群组之前发生的分类决策,使用 `inferTargetChatType`
- 对于“将其视为显式 / 原生目标 id”的检查,使用 `looksLikeId`
- `resolveTarget` 用于提供商特定的规范化回退,而不是用于宽泛的目录搜索。
- 将 chat id、thread id、JID、handle 和 room id 等提供商原生 id 保留在 `target` 值或提供商特定参数中,而不是放入通用 SDK 字段。
- 使用 `inferTargetChatType` 处理那些应在搜索联系人 / 群组之前完成的类别判断
- 使用 `looksLikeId` 处理“将其视为显式 / 原生目标 id”的检查。
- 使用 `resolveTarget` 处理提供商特定的规范化回退,而不是做宽泛的目录搜索。
- 将聊天 id、线程 id、JID、handle 和房间 id 等提供商原生 id 保存在 `target` 值或提供商特定参数中,而不是放进通用 SDK 字段。
## 基于配置的目录
## 配置支持的目录
对于从配置派生目录条目的插件,应将这部分逻辑保留在插件中,并复用
如果插件需要从配置派生目录条目,应将该逻辑保留在插件内部,并复用
`openclaw/plugin-sdk/directory-runtime` 中的共享辅助工具。
适用于以下情况:某个渠道需要基于配置的联系人 / 群组,例如:
适用场景包括渠道需要由配置支持的联系人 / 群组,例如:
- 基于 allowlist 的私信联系人
- 已配置的渠道 / 群组映射
- 按账户范围的静态目录回退
- 按账号划分的静态目录回退
`directory-runtime` 中的共享辅助工具处理通用操作:
`directory-runtime` 中的共享辅助工具处理通用操作:
- 查询过滤
- 限制应用
- 去重 / 规范化辅助工具
- 构建 `ChannelDirectoryEntry[]`
渠道特定的账检查和 id 规范化应保留在插件实现中。
渠道特定的账检查和 id 规范化应保留在插件实现中。
## 提供商目录
提供商插件可以使用
提供商插件可以通过
`registerProvider({ catalog: { run(...) { ... } } })` 定义用于推理的模型目录。
`catalog.run(...)` 返回与 OpenClaw 写入
`models.providers` 相同的结构
`catalog.run(...)` 返回的形态与 OpenClaw 写入
`models.providers` 的形态一致
- `{ provider }` 表示单个提供商条目
- `{ providers }` 表示多个提供商条目
- `{ provider }`:一个提供商条目
- `{ providers }`多个提供商条目
当插件拥有提供商特定的模型 id、基础 URL 默认值或受认证控制的模型元数据时,请使用 `catalog`
当插件拥有提供商特定的模型 id、base URL 默认值或受凭证门控的模型元数据时,请使用 `catalog`
`catalog.order` 控制插件目录相对于 OpenClaw 内置隐式提供商的合并时机:
- `simple`纯 API 密钥或基于环境变量的提供商
- `profile`:当存在证配置文件时出现的提供商
- `paired`:合成多个相关提供商条目的提供商
- `simple`普通 API key 或环境变量驱动的提供商
- `profile`:当存在证配置文件时出现的提供商
- `paired`合成多个相关提供商条目的提供商
- `late`:最后一轮,在其他隐式提供商之后
出现的提供商会在键冲突时获胜,因此插件可以有意使用相同的提供商 id 覆盖内置提供商条目。
面的提供商在键冲突时会胜出,因此插件可以有意用相同的提供商 id 覆盖内置提供商条目。
兼容性:
- `discovery` 仍然可作为旧别名使
- `discovery` 作为旧别名仍然可
- 如果同时注册了 `catalog``discovery`OpenClaw 会使用 `catalog`
## 只读渠道检查
如果你的插件注册了一个渠道,请优先实现
`plugin.config.inspectAccount(cfg, accountId)`,并同时实现 `resolveAccount(...)`
`plugin.config.inspectAccount(cfg, accountId)`,并`resolveAccount(...)` 一起提供
原因:
- `resolveAccount(...)` 是运行时路径。它可以假定凭证已被完整物化,并且在缺少必需密钥时快速失败。
- 只读命令路径,例如 `openclaw status`、`openclaw status --all`、
`openclaw channels status`、`openclaw channels resolve` 以及 doctor / 配置修复流程,不应仅为了描述配置而去物化运行时凭证。
- `resolveAccount(...)` 是运行时路径。它可以假定凭证已经完全实体化,并且在缺少必需密钥时快速失败。
- `openclaw status`、`openclaw status --all`、
`openclaw channels status`、`openclaw channels resolve` 以及 doctor / 配置修复流程这样的只读命令路径,不应该为了描述配置而去实体化运行时凭证。
推荐的 `inspectAccount(...)` 行为:
- 仅返回描述性的账状态。
- 仅返回描述性的账状态。
- 保留 `enabled``configured`
- 在相关包含凭证来源 / 状态字段,例如:
- 在相关情况下包含凭证来源 / 状态字段,例如:
- `tokenSource`、`tokenStatus`
- `botTokenSource`、`botTokenStatus`
- `appTokenSource`、`appTokenStatus`
- `signingSecretSource`、`signingSecretStatus`
- 你无需为了报告只读可用性而返回原始令牌值。返回 `tokenStatus: "available"`(以及匹配的来源字段)就足够支持状态类命令
- 为了报告只读可用性,你不需要返回原始 token 值。对于状态类命令,返回 `tokenStatus: "available"`(以及对应的来源字段)就足够了
- 当凭证通过 SecretRef 配置,但在当前命令路径中不可用时,请使用 `configured_unavailable`
这样一来,只读命令就可以报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将账户报告为未配置。
这样一来,只读命令就可以报告“已配置,但在当前命令路径中不可用”,而不是崩溃或错误地将该账号报告为未配置。
## 软件包打包集合
## 软件包打包
插件目录可以包含带有 `openclaw.extensions``package.json`
插件目录可以包含一个带有 `openclaw.extensions``package.json`
```json
{
@ -653,52 +651,46 @@ Facade 加载的入口点在存在活动运行时配置快照时会优先使用
}
```
每个条目都会成一个插件。如果该打包集合列出多个扩展,插件 id
会变 `name/<fileBase>`
每个条目都会成一个插件。如果该打包列出多个扩展,插件 id
会变 `name/<fileBase>`
如果你的插件导入了 npm 依赖,请在该目录中安装它们,以便
如果你的插件导入了 npm 依赖,请在该目录中安装这些依赖,以确保
`node_modules` 可用(`npm install` / `pnpm install`)。
安全护栏:每个 `openclaw.extensions` 条目在解析符号链接之后都必须保留在插件目录内。逃逸出软件包目录的条目会被拒绝。
安全护栏:每个 `openclaw.extensions` 条目在解析符号链接后都必须仍位于插件目录内。逃逸出软件包目录的条目会被拒绝。
安全说明:`openclaw plugins install` 会使用
`npm install --omit=dev --ignore-scripts` 安装插件依赖
(无生命周期脚本,运行时无开发依赖)。请保持插件依赖树为“纯 JS / TS”并避免使用需要 `postinstall` 构建的软件包。
`npm install --omit=dev --ignore-scripts` 安装插件依赖(不运行生命周期脚本,且运行时不安装开发依赖)。请保持插件依赖树为“纯 JS/TS”并避免使用那些需要 `postinstall` 构建的软件包。
可选:`openclaw.setupEntry` 可以指向一个轻量级、仅用于设置的模块。
当 OpenClaw 需要为已禁用的渠道插件提供设置表面时,或者当某个渠道插件已启用但仍未配置时,它会加载 `setupEntry`,而不是完整插件入口。
这样在你的主插件入口还会接线工具、钩子或其他仅运行时代码时,就能让启动和设置更轻量。
当 OpenClaw 需要为一个被禁用的渠道插件提供设置表面,或者某个渠道插件已启用但尚未配置时,它会加载 `setupEntry`,而不是完整的插件入口。这样在主插件入口还会接入工具、钩子或其他仅运行时代码的情况下,可以让启动和设置更轻量。
可选:`openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen`
以让渠道插件在 Gateway 网关的 pre-listen 启动阶段也选择同一个 `setupEntry` 路径,即使该渠道已经完成配置
让某个渠道插件在 Gateway 网关预监听启动阶段也走同样的 `setupEntry` 路径,即使该渠道已经配置完成。
仅当 `setupEntry` 完全覆盖 Gateway 网关开始监听之前必须存在的启动表面时,才应使用此项。
在实践中,这意味着设置入口必须注册启动所依赖的每一项渠道自有能力,例如:
只有当 `setupEntry` 完全覆盖了网关开始监听前必须存在的启动表面时,才应使用它。实际上,这意味着设置入口必须注册启动所依赖的每一项渠道拥有能力,例如:
- 渠道注册本身
- Gateway 网关开始监听前必须可用的所有 HTTP 路由
- 在同一时间窗口内必须存在的所有 Gateway 网关方法、工具或服务
- Gateway 网关开始监听前必须可用的所有 HTTP 路由
- 在同一时间窗口内必须存在的所有 gateway 方法、工具或服务
如果你的完整入口仍然拥有任何必需的启动能力,请不要启用此标志。
保持插件使用默认行为,并让 OpenClaw 在启动期间加载完整入口。
如果完整入口仍拥有任何必需的启动能力,就不要启用此标志。请保持插件使用默认行为,让 OpenClaw 在启动期间加载完整入口。
内置渠道可以发布仅用于设置的契约表面辅助工具,以便核心在完整渠道运行时加载前进行查询。当前的设置提升表面包括:
内置渠道可以发布仅用于设置的契约表面辅助工具,以便核心在完整渠道运行时尚未加载前进行查询。当前的设置提升表面包括:
- `singleAccountKeysToMove`
- `namedAccountPromotionKeys`
- `resolveSingleAccountPromotionTarget(...)`
当核心需要在不加载完整插件入口的情况下,将旧版单账户渠道配置提升为
当核心需要在不加载完整插件入口的情况下,将旧版单账号渠道配置提升到
`channels.<id>.accounts.*` 时,就会使用这组表面。
Matrix 是当前的内置示例:当已存在命名账户时,它只会将认证 / 引导键迁移到一个已命名的提升账户中,并且它可以保留一个已配置的非规范默认账户键,而不是总是创建
Matrix 是当前的内置示例:当已存在命名账号时,它只会把凭证 / 引导键移动到某个命名提升账号中,并且它可以保留一个已配置的、非规范默认账号键,而不是总是创建
`accounts.default`
这些设置补丁适配器使内置契约表面发现能够保持懒加载。
导入时间保持轻量;提升表面仅在首次使用时加载,而不是在模块导入时重新进入内置渠道启动流程。
这些设置补丁适配器让内置契约表面发现保持惰性。导入时间仍然很轻;提升表面只会在首次使用时加载,而不会在模块导入时重新进入内置渠道启动。
当这些启动表面包含 Gateway 网关 RPC 方法时,请将它们保留在插件专用前缀下。
核心管理命名空间(`config.*`、
`exec.approvals.*`、`wizard.*`、`update.*`)仍然是保留的,并且始终解析为 `operator.admin`,即使某个插件请求了更窄的作用域也是如此。
当这些启动表面包含 gateway RPC 方法时,请将它们保留在插件特定前缀下。核心管理命名空间(`config.*`、
`exec.approvals.*`、`wizard.*`、`update.*`)仍然保留,并且始终解析为 `operator.admin`,即使插件请求了更窄的作用域也是如此。
示例:
@ -717,7 +709,7 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会将认
### 渠道目录元数据
渠道插件可以通过 `openclaw.channel` 宣传设置 / 发现元数据,并通过 `openclaw.install` 提供安装提示。这样可以让核心目录保持无数据状态
渠道插件可以通过 `openclaw.channel` 宣传设置 / 发现元数据,并通过 `openclaw.install` 提供安装提示。这样可以让核心目录保持无数据
示例:
@ -732,7 +724,7 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会将认
"selectionLabel": "Nextcloud Talk自托管",
"docsPath": "/channels/nextcloud-talk",
"docsLabel": "nextcloud-talk",
"blurb": "通过 Nextcloud Talk webhook 机器人实现的自托管聊天。",
"blurb": "通过 Nextcloud Talk webhook 机器人提供的自托管聊天。",
"order": 65,
"aliases": ["nc-talk", "nc"]
},
@ -745,44 +737,40 @@ Matrix 是当前的内置示例:当已存在命名账户时,它只会将认
}
```
除了最小示例外,`openclaw.channel` 还有以下实用字段:
除了最小示例外,还有一些有用的 `openclaw.channel` 字段:
- `detailLabel`:用于更丰富目录 / 状态表面的次级标签
- `docsLabel`:覆盖文档链接的链接文本
- `preferOver`该目录条目应优先于哪些较低优先级的插件 / 渠道 id
- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制
- `preferOver`此目录条目应优先于哪些更低优先级的插件 / 渠道 id
- `selectionDocsPrefix`、`selectionDocsOmitLabel`、`selectionExtras`:选择表面文案控制
- `markdownCapable`:将该渠道标记为支持 Markdown以用于出站格式决策
- `exposure.configured`:设为 `false` 时,在已配置渠道列表表面中隐藏该渠道
- `exposure.setup`:设为 `false` 时,在交互式设置 / 配置选择器中隐藏该渠道
- `exposure.docs`:将该渠道标记为内部 / 私有,用于文档导航表面
- `showConfigured` / `showInSetup`出于兼容性仍接受的旧别名;优先使用 `exposure`
- `quickstartAllowFrom`:让该渠道加入标准快速开始 `allowFrom` 流程
- `forceAccountBinding`:即使只存在一个账户,也要求显式账户绑定
- `showConfigured` / `showInSetup`:仍接受的旧版兼容别名;优先使用 `exposure`
- `quickstartAllowFrom`:让该渠道接入标准的快速开始 `allowFrom` 流程
- `forceAccountBinding`:即使只存在一个账号,也要求显式账号绑定
- `preferSessionLookupForAnnounceTarget`:在解析公告目标时优先使用会话查找
OpenClaw 还可以合并**外部渠道目录**(例如 MPM
注册表导出)。将 JSON 文件放到以下任一位置:
OpenClaw 还可以合并**外部渠道目录**(例如 MPM 注册表导出)。将 JSON 文件放到以下任一位置:
- `~/.openclaw/mpm/plugins.json`
- `~/.openclaw/mpm/catalog.json`
- `~/.openclaw/plugins/catalog.json`
或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(使用逗号 / 分号 / `PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"``"plugins"` 作为 `"entries"` 键的旧别名。
或者将 `OPENCLAW_PLUGIN_CATALOG_PATHS`(或 `OPENCLAW_MPM_CATALOG_PATHS`)指向一个或多个 JSON 文件(逗号 / 分号 / `PATH` 分隔)。每个文件应包含 `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`。解析器也接受 `"packages"``"plugins"` 作为 `"entries"` 键的旧别名。
生成的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 块旁边暴露规范化后的安装来源事实。这些规范化事实会标识 npm spec 是精确版本还是浮动选择器、是否存在预期的完整性元数据,以及本地源路径是否也可用。它们还会在 `defaultChoice` 无效或指向不可用来源时发出警告,以及在存在 npm 完整性元数据但没有有效 npm 来源时发出警告。使用方应将 `installSource` 视为一个附加的可选字段,这样旧的手工构建条目和兼容性 shim 就不必合成它。这让新手引导和诊断能够解释源平面状态,而无需导入插件运行时。
生成的渠道目录条目和提供商安装目录条目会在原始 `openclaw.install` 块旁边暴露规范化后的安装来源事实。这些规范化事实可标识 npm 规格是否是精确版本还是浮动选择器、是否存在预期完整性元数据,以及是否同时存在本地源路径。当目录 / 软件包身份已知时,如果解析出的 npm 软件包名称偏离该身份,这些规范化事实会发出警告。它们还会在 `defaultChoice` 无效、指向不可用来源,或存在 npm 完整性元数据但没有有效 npm 来源时发出警告。使用方应将 `installSource` 视为附加的可选字段,这样旧的手工构建条目和兼容性 shim 就不必生成它。这样一来,新手引导和诊断就可以解释来源平面状态,而无需导入插件运行时。
官方外部 npm 条目应优先使用精确的 `npmSpec` 加上
`expectedIntegrity`。仅有软件包名和 dist-tag 仍可出于兼容性继续使用,但它们会暴露源平面警告,以便目录能够朝着固定版本、进行完整性检查的安装方式演进,而不破坏现有插件。当新手引导从本地目录路径安装时,它会记录一条
`plugins.installs` 条目,其中包含 `source: "path"`,并尽可能记录相对于工作区的 `sourcePath`。绝对的实际加载路径仍保留在
`plugins.load.paths` 中;安装记录则避免把本地工作站路径重复写入长期配置。这让本地开发安装能够被源平面诊断看到,同时不会增加第二个原始文件系统路径暴露表面。
官方外部 npm 条目应优先使用精确的 `npmSpec` 加上 `expectedIntegrity`。裸软件包名和 dist-tag 仍然可用于兼容性,但它们会暴露来源平面警告,以便目录能够在不破坏现有插件的前提下逐步转向固定版本、带完整性校验的安装。当新手引导从本地目录路径安装时,它会记录一条 `plugins.installs` 条目,并尽可能使用 `source: "path"` 和相对于工作区的 `sourcePath`。绝对操作加载路径仍保留在 `plugins.load.paths` 中;安装记录避免将本地工作站路径重复写入长期配置。这样既能让本地开发安装对来源平面诊断可见,又不会增加第二个原始文件系统路径暴露表面。
## 上下文引擎插件
上下文引擎插件拥有会话上下文编排能力,负责摄取、组装和压缩。通过
`api.registerContextEngine(id, factory)` 从你的插件注册它们,然后使用
上下文引擎插件负责会话上下文的编排,包括摄取、组装和压缩。请在你的插件中通过
`api.registerContextEngine(id, factory)` 注册它们,然后使用
`plugins.slots.contextEngine` 选择活动引擎。
当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加内存搜索或钩子时,请使用此方式。
当你的插件需要替换或扩展默认上下文流水线,而不仅仅是添加 memory 搜索或钩子时,请使用此方式。
```ts
import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
@ -810,7 +798,8 @@ export default function (api) {
}
```
如果你的引擎**不**拥有压缩算法,请仍然实现 `compact()`,并显式委托它:
如果你的引擎**不**拥有压缩算法,请保持 `compact()`
已实现,并显式委托给它:
```ts
import {
@ -847,40 +836,37 @@ export default function (api) {
## 添加新能力
当插件需要的行为无法适配当前 API 时,不要通过私有直连绕过插件系统。请添加缺失的能力。
当插件需要当前 API 无法适配的行为时,不要通过私有内部穿透来绕过插件系统。应添加缺失的能力。
推荐顺序:
1. 定义核心契约
决定核心应拥有哪些共享行为:策略、回退、配置合并、
生命周期、面向渠道的语义以及运行时辅助工具形态。
2. 添加类型化插件注册 / 运行时表面
以最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和 / 或 `api.runtime`
3. 接通核心 + 渠道 / 功能使用方
渠道和功能插件应通过核心消费新能力,
而不是直接导入某个供应商实现。
4. 注册供应商实现
然后由供应商插件将其后端注册到该能力上。
决定哪些共享行为应由核心负责:策略、回退、配置合并、生命周期、面向渠道的语义以及运行时辅助工具形态。
2. 添加类型化的插件注册 / 运行时表面
用最小但有用的类型化能力表面扩展 `OpenClawPluginApi` 和 / 或 `api.runtime`
3. 连接核心 + 渠道 / 功能使用方
渠道和功能插件应通过核心消费该新能力,而不是直接导入某个厂商实现。
4. 注册厂商实现
然后由厂商插件根据该能力注册它们的后端实现。
5. 添加契约覆盖
添加测试,以便随着时间推移,所有权和注册形态仍保持明确。
添加测试,以便随着时间推移,所有权和注册形态仍保持明确。
这就是 OpenClaw 在保持鲜明主张的同时,不会被硬编码到某一家提供商世界观中的方式。有关具体文件检查清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
这就是 OpenClaw 在保持鲜明主张的同时,又不至于硬编码到某个提供商世界观中的方式。有关具体文件清单和完整示例,请参见 [能力扩展手册](/zh-CN/plugins/architecture)。
### 能力检查清单
当你添加一个新能力时,实现通常应同时触及以下表面:
当你添加一个新能力时,实现通常应同时覆盖这些表面:
- `src/<capability>/types.ts` 中的核心契约类型
- `src/<capability>/runtime.ts` 中的核心运行器 / 运行时辅助工具
- `src/plugins/types.ts` 中的插件 API 注册表面
- `src/plugins/registry.ts` 中的插件注册表接线
- `src/plugins/runtime/*` 中的插件运行时暴露(当功能 / 渠道
插件需要消费它时)
- 当功能 / 渠道插件需要消费它时,`src/plugins/runtime/*` 中的插件运行时暴露
- `src/test-utils/plugin-registration.ts` 中的捕获 / 测试辅助工具
- `src/plugins/contracts/registry.ts` 中的所有权 / 契约断言
- `docs/` 中面向运维人员 / 插件的文档
如果这些表面中有某一项缺失,通常意味着该能力尚未被完全集成。
如果这些表面中缺少某一个,通常说明该能力还没有被完全集成。
### 能力模板
@ -916,16 +902,16 @@ const clip = await api.runtime.videoGeneration.generate({
expect(findVideoGenerationProviderIdsForPlugin("openai")).toEqual(["openai"]);
```
这样就能保持规则简单:
这样规则就很简单:
- 核心拥有能力契约 + 编排
- 供应商插件拥有供应商实现
- 厂商插件拥有厂商实现
- 功能 / 渠道插件消费运行时辅助工具
- 契约测试保持所有权明确
- 契约测试让所有权保持明确
## 相关内容
- [Plugin architecture](/zh-CN/plugins/architecture) — 公开能力模型和形态
- [Plugin SDK subpaths](/zh-CN/plugins/sdk-subpaths)
- [Plugin SDK setup](/zh-CN/plugins/sdk-setup)
- [Building plugins](/zh-CN/plugins/building-plugins)
- [插件架构](/zh-CN/plugins/architecture) —— 公共能力模型和形态
- [插件 SDK 子路径](/zh-CN/plugins/sdk-subpaths)
- [插件 SDK 设置](/zh-CN/plugins/sdk-setup)
- [构建插件](/zh-CN/plugins/building-plugins)

View File

@ -1,21 +1,21 @@
---
read_when:
- 你正在构建一个 OpenClaw 插件
- 你需要发布一个插件配置 schema或调试插件校验错误
- 你需要提供一个插件配置 schema或调试插件校验错误
summary: 插件清单 + JSON schema 要求(严格配置校验)
title: 插件清单
x-i18n:
generated_at: "2026-04-24T16:05:38Z"
generated_at: "2026-04-24T16:35:15Z"
model: gpt-5.4
provider: openai
source_hash: 44eca8a54f22735ae657efde088a7951eeb79dfbb48a25d478c7e9a3f699cce0
source_hash: 47e3d70e4a49eece9087b8cd0a21955e3290306f5962855bbed61854f59ac08f
source_path: plugins/manifest.md
workflow: 15
---
此页面仅适用于**原生 OpenClaw 插件清单**。
此页面仅适用于 **原生 OpenClaw 插件清单**
关于兼容的 bundle 布局,请参见 [插件 bundles](/zh-CN/plugins/bundles)。
关于兼容的 bundle 布局,请参阅 [Plugin bundles](/zh-CN/plugins/bundles)。
兼容的 bundle 格式使用不同的清单文件:
@ -23,31 +23,31 @@ x-i18n:
- Claude bundle`.claude-plugin/plugin.json`,或不带清单的默认 Claude 组件布局
- Cursor bundle`.cursor-plugin/plugin.json`
OpenClaw 也会自动检测这些 bundle 布局,但不会根据此处描述的 `openclaw.plugin.json` schema 对它们进行校验。
OpenClaw 也会自动检测这些 bundle 布局,但它们不会根据此处介绍的 `openclaw.plugin.json` schema 进行校验。
对于兼容 bundleOpenClaw 当前会在布局符合 OpenClaw 运行时预期时,读取 bundle 元数据、已声明的 skill 根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及支持的 hook packs
对于兼容 bundle当其布局符合 OpenClaw 运行时预期时OpenClaw 当前会读取 bundle 元数据、已声明的技能根目录、Claude 命令根目录、Claude bundle `settings.json` 默认值、Claude bundle LSP 默认值,以及支持的 hook pack。
每个原生 OpenClaw 插件**必须**在**插件根目录**中提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用这个清单在**不执行插件代码的情况下**校验配置。缺失或无效的清单会被视为插件错误,并阻止配置校验。
每个原生 OpenClaw 插件**必须****插件根目录** 提供一个 `openclaw.plugin.json` 文件。OpenClaw 使用此清单在 **不执行插件代码的情况下** 校验配置。缺失或无效的清单会被视为插件错误,并阻止配置校验。
查看完整的插件系统指南:[插件](/zh-CN/tools/plugin)。
关于原生能力模型和当前的外部兼容性指南,请参见
[能力模型](/zh-CN/plugins/architecture#public-capability-model)。
查看完整的插件系统指南:[Plugins](/zh-CN/tools/plugin)。
关于原生能力模型和当前外部兼容性指南,请参阅
[Capability model](/zh-CN/plugins/architecture#public-capability-model)。
## 此文件的作用
`openclaw.plugin.json` 是 OpenClaw 在**加载你的插件代码之前**读取的元数据。下面的所有内容都必须足够轻量,以便无需启动插件运行时即可检查。
`openclaw.plugin.json` 是 OpenClaw 在 **加载你的插件代码之前** 读取的元数据。下面的所有内容都必须足够轻量,能够在不启动插件运行时的情况下完成检查。
**用于:**
- 插件标识、配置校验配置 UI 提示
- 插件标识、配置校验,以及配置 UI 提示
- 凭证、onboarding 和设置元数据(别名、自动启用、提供商环境变量、凭证选项)
- 控制平面面的激活提示
- 简写的模型族归属
- 控制平面面的激活提示
- 简写的模型族归属
- 静态能力归属快照(`contracts`
- 共享 `openclaw qa` 宿主检查的 QA 运行器元数据
- 合并到目录和校验面的渠道专属配置元数据
- 共享 `openclaw qa` 宿主检查的 QA 运行器元数据
- 合并到目录和校验面的渠道专属配置元数据
**不要用于:**注册运行时行为、声明代码入口点或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
**不要用于:** 注册运行时行为、声明代码入口点或 npm 安装元数据。这些应放在你的插件代码和 `package.json` 中。
## 最小示例
@ -129,64 +129,64 @@ OpenClaw 也会自动检测这些 bundle 布局,但不会根据此处描述的
| 字段 | 必填 | 类型 | 含义 |
| ------------------------------------ | -------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | 是 | `string` | 规范的插件 id。这是 `plugins.entries.<id>` 中使用的 id。 |
| `id` | 是 | `string` | 规范的插件 id。这是 `plugins.entries.<id>` 中使用的 id。 |
| `configSchema` | 是 | `object` | 此插件配置的内联 JSON Schema。 |
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略它,或设置为任何非 `true` 的值,则插件默认保持禁用。 |
| `legacyPluginIds` | 否 | `string[]` | 会规范化为此标准插件 id 的旧版 id。 |
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当凭证、配置或模型引用提到这些 provider id 时,应自动启用此插件。 |
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明一个由 `plugins.slots.*` 使用的互斥插件类型。 |
| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于发现和配置校验。 |
| `enabledByDefault` | 否 | `true` | 将内置插件标记为默认启用。省略此字段,或将其设为任何非 `true` 的值,则该插件默认保持禁用。 |
| `legacyPluginIds` | 否 | `string[]` | 会规范化为此规范插件 id 的旧版 id。 |
| `autoEnableWhenConfiguredProviders` | 否 | `string[]` | 当凭证、配置或模型引用提到这些提供商 id 时,应自动启用此插件。 |
| `kind` | 否 | `"memory"` \| `"context-engine"` | 声明 `plugins.slots.*` 使用的互斥插件类型。 |
| `channels` | 否 | `string[]` | 由此插件拥有的渠道 id。用于设备发现和配置校验。 |
| `providers` | 否 | `string[]` | 由此插件拥有的提供商 id。 |
| `providerDiscoveryEntry` | 否 | `string` | 轻量级 provider 发现模块路径,相对于插件根目录,用于作用域限定在清单内的 provider 目录元数据;这些元数据在不激活完整插件运行时的情况下加载。 |
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型族元数据,用于在运行时之前自动加载插件。 |
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint host/baseUrl 元数据,用于核心在 provider 运行时加载前对 provider 路由进行分类。 |
| `providerDiscoveryEntry` | 否 | `string` | 轻量级提供商发现模块路径,相对于插件根目录,用于可在不激活完整插件运行时的情况下加载的、限定于清单作用域的提供商目录元数据。 |
| `modelSupport` | 否 | `object` | 由清单拥有的简写模型族元数据,用于在运行时之前自动加载插件。 |
| `providerEndpoints` | 否 | `object[]` | 由清单拥有的 endpoint host/baseUrl 元数据,用于核心在提供商运行时加载之前对提供商路由进行分类。 |
| `cliBackends` | 否 | `string[]` | 由此插件拥有的 CLI 推理后端 id。用于根据显式配置引用在启动时自动激活。 |
| `syntheticAuthRefs` | 否 | `string[]` | provider 或 CLI 后端引用;在运行时加载之前的冷启动模型发现阶段,应探测其由插件拥有的 synthetic auth hook。 |
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API key 值,用于表示非密的本地、OAuth 或环境凭证状态。 |
| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称;在运行时加载之前,这些命令应产生具备插件感知能力的配置和 CLI 诊断信息。 |
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | 开销较低的 provider 凭证环境变量元数据OpenClaw 无需加载插件代码即可检查。 |
| `providerAuthAliases` | 否 | `Record<string, string>` | 应重用另一个 provider id 进行凭证查找的 provider id例如共享基础 provider API key 和凭证配置文件的 coding provider。 |
| `channelEnvVars` | 否 | `Record<string, string[]>` | 开销较低的渠道环境变量元数据OpenClaw 无需加载插件代码即可检查。对于由环境变量驱动的渠道设置或通用启动/配置辅助工具应可见的凭证表面,请使用此项。 |
| `providerAuthChoices` | 否 | `object[]` | 开销较低的凭证选项元数据,用于 onboarding 选择器、首选 provider 解析以及简单的 CLI 标志接线。 |
| `activation` | 否 | `object` | 开销较低的激活规划器元数据,用于由 provider、命令、渠道、路由和能力触发的加载。仅为元数据;实际行为仍由插件运行时负责。 |
| `setup` | 否 | `object` | 开销较低的设置 / onboarding 描述符,供发现和设置表面在不加载插件运行时的情况下检查。 |
| `qaRunners` | 否 | `object[]` | 开销较低的 QA 运行器描述符,供共享 `openclaw qa` 宿主在插件运行时加载前使用。 |
| `contracts` | 否 | `object` | 面向外部凭证 hooks、语音、实时转录、实时语音、媒体理解、图像生成、音乐生成、视频生成、web 抓取、Web 搜索以及工具归属的静态内置能力快照。 |
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 为 `contracts.mediaUnderstandingProviders` 中声明的 provider id 提供的低开销媒体理解默认值。 |
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到发现和校验表面中。 |
| `syntheticAuthRefs` | 否 | `string[]` | 在运行时加载之前的冷启动模型发现阶段,应探测其插件自有 synthetic auth hook 的提供商或 CLI 后端引用。 |
| `nonSecretAuthMarkers` | 否 | `string[]` | 由内置插件拥有的占位 API key 值,表示非密的本地、OAuth 或环境凭证状态。 |
| `commandAliases` | 否 | `object[]` | 由此插件拥有的命令名称,应在运行时加载前产生具备插件感知能力的配置和 CLI 诊断信息。 |
| `providerAuthEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级提供商凭证环境变量元数据。 |
| `providerAuthAliases` | 否 | `Record<string, string>` | 应复用另一个提供商 id 进行凭证查找的提供商 id例如共享基础提供商 API key 和凭证配置文件的 coding 提供商。 |
| `channelEnvVars` | 否 | `Record<string, string[]>` | OpenClaw 可在不加载插件代码的情况下检查的轻量级渠道环境变量元数据。将其用于通用启动 / 配置辅助功能应看到的、由环境变量驱动的渠道设置或凭证界面。 |
| `providerAuthChoices` | 否 | `object[]` | 用于 onboarding 选择器、首选提供商解析和简单 CLI 标志接线的轻量级凭证选项元数据。 |
| `activation` | 否 | `object` | 用于提供商、命令、渠道、路由和能力触发加载的轻量级激活规划器元数据。仅为元数据;实际行为仍由插件运行时负责。 |
| `setup` | 否 | `object` | 轻量级设置 / onboarding 描述符,供设备发现和设置界面在不加载插件运行时的情况下检查。 |
| `qaRunners` | 否 | `object[]` | 共享 `openclaw qa` 宿主在插件运行时加载前使用的轻量级 QA 运行器描述符。 |
| `contracts` | 否 | `object` | 面向外部凭证 hook、语音、实时转写、实时语音、媒体理解、图像生成、音乐生成、视频生成、web 获取、Web 搜索和工具归属的静态内置能力快照。 |
| `mediaUnderstandingProviderMetadata` | 否 | `Record<string, object>` | 为 `contracts.mediaUnderstandingProviders` 中声明的提供商 id 提供的轻量级媒体理解默认元数据。 |
| `channelConfigs` | 否 | `Record<string, object>` | 由清单拥有的渠道配置元数据,在运行时加载前合并到设备发现和校验界面中。 |
| `skills` | 否 | `string[]` | 要加载的 Skills 目录,相对于插件根目录。 |
| `name` | 否 | `string` | 人类可读的插件名称。 |
| `description` | 否 | `string` | 显示在插件表面中的简短摘要。 |
| `version` | 否 | `string` | 信息性插件版本。 |
| `description` | 否 | `string` | 在插件界面中显示的简短摘要。 |
| `version` | 否 | `string` | 信息性插件版本。 |
| `uiHints` | 否 | `Record<string, object>` | 配置字段的 UI 标签、占位符和敏感性提示。 |
## `providerAuthChoices` 参考
每个 `providerAuthChoices` 条目描述一 onboarding 或凭证选项。
OpenClaw 会在 provider 运行时加载之前读取它
每个 `providerAuthChoices` 条目描述一 onboarding 或凭证选项。
OpenClaw 会在提供商运行时加载之前读取这些内容
| 字段 | 必填 | 类型 | 含义 |
| --------------------- | -------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `provider` | 是 | `string` | 此选项所属的 provider id。 |
| `provider` | 是 | `string` | 此选项所属的提供商 id。 |
| `method` | 是 | `string` | 要分发到的凭证方法 id。 |
| `choiceId` | 是 | `string` | onboarding 和 CLI 流程使用的稳定凭证选项 id。 |
| `choiceLabel` | 否 | `string` | 面向用户的标签。如省略OpenClaw 会回退到 `choiceId`。 |
| `choiceHint` | 否 | `string` | 选择器中的简短辅助说明文本。 |
| `choiceLabel` | 否 | `string` | 面向用户的标签。如省略OpenClaw 会回退到 `choiceId`。 |
| `choiceHint` | 否 | `string` | 选择器的简短帮助文本。 |
| `assistantPriority` | 否 | `number` | 在由智能体驱动的交互式选择器中,值越小排序越靠前。 |
| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在智能体选择器中隐藏选项,但仍允许手动通过 CLI 选择。 |
| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到当前替代选项的旧版选项 id。 |
| `groupId` | 否 | `string` | 用于对相关选项进行分组的可选组 id。 |
| `assistantVisibility` | 否 | `"visible"` \| `"manual-only"` | 在智能体选择器中隐藏选项,但仍允许手动通过 CLI 选择。 |
| `deprecatedChoiceIds` | 否 | `string[]` | 应将用户重定向到替代选项的旧版选项 id。 |
| `groupId` | 否 | `string` | 用于对相关选项分组的可选组 id。 |
| `groupLabel` | 否 | `string` | 该分组面向用户的标签。 |
| `groupHint` | 否 | `string` | 该分组的简短辅助说明文本。 |
| `groupHint` | 否 | `string` | 该分组的简短帮助文本。 |
| `optionKey` | 否 | `string` | 用于简单单标志凭证流程的内部选项键。 |
| `cliFlag` | 否 | `string` | CLI 标志名称,例如 `--openrouter-api-key`。 |
| `cliOption` | 否 | `string` | 完整的 CLI 选项形式,例如 `--openrouter-api-key <key>`。 |
| `cliDescription` | 否 | `string` | CLI 帮助中使用的描述。 |
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选项应出现在哪些 onboarding 表面中。如果省略,默认值为 `["text-inference"]`。 |
| `onboardingScopes` | 否 | `Array<"text-inference" \| "image-generation">` | 此选项应出现在哪些 onboarding 界面中。如省略,默认值为 `["text-inference"]`。 |
## `commandAliases` 参考
当插件拥有某个运行时命令名称,而用户可能会误将其放入 `plugins.allow` 或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用这些元数据在不导入插件运行时代码的情况下提供诊断信息。
当插件拥有某个运行时命令名称,而用户可能错误地将其放入 `plugins.allow` 或尝试将其作为根 CLI 命令运行时,请使用 `commandAliases`。OpenClaw 使用这些元数据在不导入插件运行时代码的情况下提供诊断信息。
```json
{
@ -203,18 +203,18 @@ OpenClaw 会在 provider 运行时加载之前读取它。
| 字段 | 必填 | 类型 | 含义 |
| ------------ | -------- | ----------------- | ----------------------------------------------------------------------- |
| `name` | 是 | `string` | 属于此插件的命令名称。 |
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
| `cliCommand` | 否 | `string` | 如存在,用于建议 CLI 操作的相关根 CLI 命令。 |
| `kind` | 否 | `"runtime-slash"` | 将该别名标记为聊天斜杠命令,而不是根 CLI 命令。 |
| `cliCommand` | 否 | `string` | 如存在,用于 CLI 操作时建议的相关根 CLI 命令。 |
## `activation` 参考
当插件可以低成本声明哪些控制平面事件应将其纳入激活 / 加载计划时,请使用 `activation`
当插件可以低成本声明哪些控制平面事件应将其纳入激活 / 加载计划时,请使用 `activation`
此块是规划器元数据,而不是生命周期 API。它不会注册运行时行为不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks之前缩小候选插件范围。
代码块是规划器元数据,而不是生命周期 API。它不会注册运行时行为不会替代 `register(...)`,也不保证插件代码已经执行。激活规划器使用这些字段在回退到现有清单归属元数据(如 `providers`、`channels`、`commandAliases`、`setup.providers`、`contracts.tools` 和 hooks之前,先缩小候选插件范围。
优先使用已经描述归属关系的最窄元数据。如果这些字段能够表达该关系,请使用 `providers`、`channels`、`commandAliases`、setup 描述符或 `contracts`。只有在这些归属字段无法表示额外规划器提示时,才使用 `activation`
优先使用已经描述归属关系的最窄元数据。如果 `providers`、`channels`、`commandAliases`、设置描述符或 `contracts` 已能表达这种关系,就使用这些字段。对于无法用这些归属字段表示的额外规划器提示,再使用 `activation`
块仅为元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。当前使用方会在更广泛的插件加载之前将其作为缩小范围的提示,因此缺失激活元数据通常只会带来性能成本;只要旧版清单归属回退仍然存在,它就不应影响正确性。
代码块仅是元数据。它不会注册运行时行为,也不会替代 `register(...)`、`setupEntry` 或其他运行时 / 插件入口点。当前使用方会在更广泛的插件加载之前,将其作为缩小范围的提示,因此缺少激活元数据通常只会带来性能损耗;只要旧版清单归属回退仍然存在,它就不应改变正确性。
```json
{
@ -230,26 +230,27 @@ OpenClaw 会在 provider 运行时加载之前读取它。
| 字段 | 必填 | 类型 | 含义 |
| ---------------- | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的 provider id。 |
| `onProviders` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的提供商 id。 |
| `onCommands` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的命令 id。 |
| `onChannels` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的渠道 id。 |
| `onRoutes` | 否 | `string[]` | 应将此插件纳入激活 / 加载计划的路由类型。 |
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 控制平面激活规划使用的宽泛能力提示。能用更窄字段优先使用更窄字段。 |
| `onCapabilities` | 否 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 控制平面激活规划使用的宽泛能力提示。能时优先使用更窄字段。 |
当前在线使用方:
- 由命令触发的 CLI 规划会回退到旧版
- 由命令触发的 CLI 规划会回退到旧版
`commandAliases[].cliCommand``commandAliases[].name`
- 由渠道触发的设置 / 渠道规划会在缺少显式渠道激活元数据时,回退到旧版 `channels[]`
归属
- 由 provider 触发的设置 / 运行时规划会在缺少显式 provider
激活元数据时,回退到旧版 `providers[]` 和顶层 `cliBackends[]` 归属
- 由渠道触发的设置 / 渠道规划在缺少显式渠道激活元数据时,
会回退到旧版 `channels[]` 归属
- 由提供商触发的设置 / 运行时规划在缺少显式提供商
激活元数据时,会回退到旧版
`providers[]` 和顶层 `cliBackends[]` 归属
规划器诊断可以区分显式激活提示清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用 `commandAliases` 归属。这些原因标签用于宿主诊断和测试;插件作者应继续声明最能描述归属关系的元数据。
规划器诊断可以区分显式激活提示清单归属回退。例如,`activation-command-hint` 表示匹配了 `activation.onCommands`,而 `manifest-command-alias` 表示规划器改为使用 `commandAliases` 归属。这些原因标签用于宿主诊断和测试;插件作者应继续声明最能描述归属关系的元数据。
## `qaRunners` 参考
当插件在共享 `openclaw qa` 根命令下提供一个或多个传输运行器时,请使用 `qaRunners`。保持这些元数据轻量且静态;实际的 CLI 注册仍由插件运行时通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 面负责。
当插件在共享 `openclaw qa` 根命令下提供一个或多个传输运行器时,请使用 `qaRunners`。保持这些元数据轻量且静态;实际的 CLI 注册仍由插件运行时通过导出 `qaRunnerCliRegistrations` 的轻量级 `runtime-api.ts` 面负责。
```json
{
@ -269,7 +270,7 @@ OpenClaw 会在 provider 运行时加载之前读取它。
## `setup` 参考
当设置和 onboarding 表面在运行时加载前需要低成本的插件自有元数据时,请使用 `setup`
当设置和 onboarding 界面需要在运行时加载前读取由插件拥有的轻量级元数据时,请使用 `setup`
```json
{
@ -288,32 +289,32 @@ OpenClaw 会在 provider 运行时加载之前读取它。
}
```
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是面向控制平面 / 设置流程的设置专用描述符表面,应保持为仅元数据。
顶层 `cliBackends` 仍然有效,并继续描述 CLI 推理后端。`setup.cliBackends` 是用于控制平面 / 设置流程的设置专用描述符界面,应保持为仅元数据。
存在时,`setup.providers` 和 `setup.cliBackends` 是设置发现时优先使用的 descriptor-first 查找表面。如果描述符只缩小候选插件范围,而设置仍需要更丰富的设置阶段运行时 hooks请设置 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。
存在时,`setup.providers` 和 `setup.cliBackends` 是设置发现时首选的 descriptor-first 查找界面。如果描述符只能缩小候选插件范围,而设置仍需要更丰富的设置期运行时 hook请设定 `requiresRuntime: true`,并保留 `setup-api` 作为回退执行路径。
由于设置查找可能会执行插件自有的 `setup-api` 代码,因此规范化后的 `setup.providers[].id``setup.cliBackends[]` 值必须在已发现的插件之间保持唯一。归属关系有歧义时会采用失败关闭,而不是按发现顺序选择一个赢家。
由于设置查找可能会执行插件自有的 `setup-api` 代码,因此规范化后的 `setup.providers[].id``setup.cliBackends[]` 值必须在所有已发现插件中保持唯一。若归属关系有歧义,系统会采用失败即关闭的策略,而不是按发现顺序选出一个赢家。
### `setup.providers` 参考
| 字段 | 必填 | 类型 | 含义 |
| ------------- | -------- | ---------- | ------------------------------------------------------------------------------------ |
| `id` | 是 | `string` | 在设置或 onboarding 期间暴露的 provider id。保持规范化 id 在全局范围内唯一。 |
| `authMethods` | 否 | `string[]` | 该 provider 在不加载完整运行时的情况下支持的设置 / 凭证方法 id。 |
| `envVars` | 否 | `string[]` | 通用设置 / 状态表面在插件运行时加载前可检查的环境变量。 |
| `id` | 是 | `string` | 在设置或 onboarding 期间暴露的提供商 id。保持规范化 id 在全局唯一。 |
| `authMethods` | 否 | `string[]` | 此提供商在无需加载完整运行时的情况下支持的设置 / 凭证方法 id。 |
| `envVars` | 否 | `string[]` | 通用设置 / 状态界面可在插件运行时加载前检查的环境变量。 |
### `setup` 字段
| 字段 | 必填 | 类型 | 含义 |
| ------------------ | -------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间暴露的 provider 设置描述符。 |
| `cliBackends` | 否 | `string[]` | 用于 descriptor-first 设置查找的设置阶段后端 id。保持规范化 id 在全局范围内唯一。 |
| `configMigrations` | 否 | `string[]` | 属于此插件设置表面的配置迁移 id。 |
| `providers` | 否 | `object[]` | 在设置和 onboarding 期间暴露的提供商设置描述符。 |
| `cliBackends` | 否 | `string[]` | descriptor-first 设置查找使用的设置期后端 id。保持规范化 id 在全局唯一。 |
| `configMigrations` | 否 | `string[]` | 由此插件的设置界面拥有的配置迁移 id。 |
| `requiresRuntime` | 否 | `boolean` | 在描述符查找之后,设置是否仍需要执行 `setup-api`。 |
## `uiHints` 参考
`uiHints` 是从配置字段名到小型渲染提示的映射。
`uiHints` 是从配置字段名到小型渲染提示的映射。
```json
{
@ -328,20 +329,20 @@ OpenClaw 会在 provider 运行时加载之前读取它。
}
```
每个字段提示可包含:
每个字段提示可包含:
| 字段 | 类型 | 含义 |
| ------------- | ---------- | --------------------------------------- |
| `label` | `string` | 面向用户的字段标签。 |
| `help` | `string` | 简短的辅助说明文本。 |
| `help` | `string` | 简短帮助文本。 |
| `tags` | `string[]` | 可选的 UI 标签。 |
| `advanced` | `boolean` | 将该字段标记为高级字段。 |
| `sensitive` | `boolean` | 将该字段标记为密或敏感字段。 |
| `sensitive` | `boolean` | 将该字段标记为密或敏感字段。 |
| `placeholder` | `string` | 表单输入的占位文本。 |
## `contracts` 参考
仅在 OpenClaw 可以在不导入插件运行时的情况下读取静态能力归属元数据时使用 `contracts`
仅在 OpenClaw 可以在不导入插件运行时的情况下读取静态能力归属元数据时,才使用 `contracts`
```json
{
@ -367,25 +368,25 @@ OpenClaw 会在 provider 运行时加载之前读取它。
| 字段 | 类型 | 含义 |
| -------------------------------- | ---------- | ----------------------------------------------------------------- |
| `embeddedExtensionFactories` | `string[]` | 内置插件可为其注册工厂的嵌入式运行时 id。 |
| `externalAuthProviders` | `string[]` | 此插件拥有其外部凭证配置文件 hook 的 provider id。 |
| `speechProviders` | `string[]` | 此插件拥有的语音 provider id。 |
| `realtimeTranscriptionProviders` | `string[]` | 此插件拥有的实时转录 provider id。 |
| `realtimeVoiceProviders` | `string[]` | 此插件拥有的实时语音 provider id。 |
| `memoryEmbeddingProviders` | `string[]` | 此插件拥有的 Memory 嵌入 provider id。 |
| `mediaUnderstandingProviders` | `string[]` | 此插件拥有的媒体理解 provider id。 |
| `imageGenerationProviders` | `string[]` | 此插件拥有的图像生成 provider id。 |
| `videoGenerationProviders` | `string[]` | 此插件拥有的视频生成 provider id。 |
| `webFetchProviders` | `string[]` | 此插件拥有的 web 抓取 provider id。 |
| `webSearchProviders` | `string[]` | 此插件拥有的 Web 搜索 provider id。 |
| `tools` | `string[]` | 此插件为内置契约检查所拥有的智能体工具名称。 |
| `externalAuthProviders` | `string[]` | 其外部凭证配置文件 hook 由此插件拥有的提供商 id。 |
| `speechProviders` | `string[]` | 由此插件拥有的语音提供商 id。 |
| `realtimeTranscriptionProviders` | `string[]` | 由此插件拥有的实时转写提供商 id。 |
| `realtimeVoiceProviders` | `string[]` | 由此插件拥有的实时语音提供商 id。 |
| `memoryEmbeddingProviders` | `string[]` | 由此插件拥有的 Memory 嵌入提供商 id。 |
| `mediaUnderstandingProviders` | `string[]` | 由此插件拥有的媒体理解提供商 id。 |
| `imageGenerationProviders` | `string[]` | 由此插件拥有的图像生成提供商 id。 |
| `videoGenerationProviders` | `string[]` | 由此插件拥有的视频生成提供商 id。 |
| `webFetchProviders` | `string[]` | 由此插件拥有的 web 获取提供商 id。 |
| `webSearchProviders` | `string[]` | 由此插件拥有的 Web 搜索提供商 id。 |
| `tools` | `string[]` | 在内置契约检查中由此插件拥有的智能体工具名称。 |
实现 `resolveExternalAuthProfiles` 的 provider 插件应声明 `contracts.externalAuthProviders`。未声明的插件仍会通过已弃用的兼容性回退路径运行,但该回退路径更慢,并将在迁移窗口结束后移除。
实现`resolveExternalAuthProfiles` 的提供商插件应声明 `contracts.externalAuthProviders`。未作此声明的插件仍会通过已弃用的兼容性回退路径运行,但该回退更慢,并将在迁移窗口结束后移除。
内置 Memory 嵌入 provider 应为其公开的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括内建适配器,例如 `local`。独立的 CLI 路径使用此清单契约,在完整 Gateway 网关 运行时注册 provider 之前,仅加载所属插件。
内置的 Memory 嵌入提供商应为其暴露的每个适配器 id 声明 `contracts.memoryEmbeddingProviders`,包括像 `local` 这样的内置适配器。独立 CLI 路径使用此清单契约,在完整 Gateway 网关运行时注册提供商之前,仅加载其所属插件。
## `mediaUnderstandingProviderMetadata` 参考
媒体理解 provider 具有默认模型、自动凭证回退优先级或通用核心辅助工具在运行时加载前需要的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`。键也必须在 `contracts.mediaUnderstandingProviders` 中声明。
某个媒体理解提供商具有默认模型、自动凭证回退优先级,或通用核心辅助功能在运行时加载前所需的原生文档支持时,请使用 `mediaUnderstandingProviderMetadata`键也必须在 `contracts.mediaUnderstandingProviders` 中声明。
```json
{
@ -408,18 +409,18 @@ OpenClaw 会在 provider 运行时加载之前读取它。
}
```
每个 provider 条目可以包含:
每个提供商条目可包含:
| 字段 | 类型 | 含义 |
| ---------------------- | ----------------------------------- | ---------------------------------------------------------------------------- |
| `capabilities` | `("image" \| "audio" \| "video")[]` | 此 provider 公开的媒体能力。 |
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时使用的能力到模型默认映射。 |
| `autoPriority` | `Record<string, number>` | 用于基于凭证的自动 provider 回退时,数字越小排序越靠前。 |
| `nativeDocumentInputs` | `"pdf"[]` | provider 支持的原生文档输入。 |
| `capabilities` | `("image" \| "audio" \| "video")[]` | 此提供商暴露的媒体能力。 |
| `defaultModels` | `Record<string, string>` | 当配置未指定模型时使用的能力到模型默认映射。 |
| `autoPriority` | `Record<string, number>` | 用于基于凭证的自动提供商回退时,数字越小排序越靠前。 |
| `nativeDocumentInputs` | `"pdf"[]` | 此提供商支持的原生文档输入。 |
## `channelConfigs` 参考
当渠道插件在运行时加载前需要低成本配置元数据时,请使用 `channelConfigs`
当渠道插件在运行时加载前需要轻量级配置元数据时,请使用 `channelConfigs`
```json
{
@ -446,19 +447,19 @@ OpenClaw 会在 provider 运行时加载之前读取它。
}
```
每个渠道条目可包含:
每个渠道条目可包含:
| 字段 | 类型 | 含义 |
| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
| `schema` | `object` | `channels.<id>` 的 JSON Schema。每个已声明的渠道配置条目都必须提供。 |
| `uiHints` | `Record<string, object>` | 该渠道配置部分可选的 UI 标签 / 占位符 / 敏感性提示。 |
| `label` | `string` | 当运行时元数据尚未就绪时,合并到选择器和检查表面中的渠道标签。 |
| `description` | `string` | 用于检查和目录面的简短渠道描述。 |
| `preferOver` | `string[]` | 此渠道在选择表面中应优先于的旧版或低优先级插件 id。 |
| `label` | `string` | 当运行时元数据尚未准备好时,合并到选择器和检查界面中的渠道标签。 |
| `description` | `string` | 用于检查和目录面的简短渠道描述。 |
| `preferOver` | `string[]` | 在选择界面中,此渠道应优先于的旧版或较低优先级插件 id。 |
## `modelSupport` 参考
当 OpenClaw 应在插件运行时加载前,根据像 `gpt-5.5``claude-sonnet-4.6` 这样的简写模型 id 推断你的 provider 插件时,请使用 `modelSupport`
当 OpenClaw 需要在插件运行时加载前,根据 `gpt-5.5``claude-sonnet-4.6` 这类简写模型 id 推断出你的提供商插件时,请使用 `modelSupport`
```json
{
@ -469,70 +470,69 @@ OpenClaw 会在 provider 运行时加载之前读取它。
}
```
OpenClaw 按以下优先级应用
OpenClaw 采用以下优先级
- 显式 `provider/model` 引用使用所属 `providers` 清单元数据
- 显式 `provider/model` 引用使用所属 `providers` 清单元数据
- `modelPatterns` 优先于 `modelPrefixes`
- 如果一个非内置插件和一个内置插件都匹配,则非内置插件胜出
- 如果仍有歧义,则在用户或配置指定 provider 之前忽略该歧义
- 剩余歧义将被忽略,直到用户或配置显式指定提供商
字段:
| 字段 | 类型 | 含义 |
| --------------- | ---------- | ------------------------------------------------------------------------------- |
| `modelPrefixes` | `string[]` | 使用 `startsWith` 对简写模型 id 进行匹配的前缀。 |
| `modelPrefixes` | `string[]` | 通过 `startsWith` 与简写模型 id 匹配的前缀。 |
| `modelPatterns` | `string[]` | 在移除配置文件后缀后,与简写模型 id 匹配的正则表达式源码。 |
旧版顶层能力键已弃用。使用 `openclaw doctor --fix``speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;普通清单加载不再将这些顶层字段视为能力归属。
旧版顶层能力键已弃用。使用 `openclaw doctor --fix``speechProviders`、`realtimeTranscriptionProviders`、`realtimeVoiceProviders`、`mediaUnderstandingProviders`、`imageGenerationProviders`、`videoGenerationProviders`、`webFetchProviders` 和 `webSearchProviders` 移动到 `contracts` 下;常规清单加载不再将这些顶层字段视为能力归属声明
## 清单与 `package.json` 的区别
这两个文件承担不同职责:
这两个文件承担不同职责:
| 文件 | 用途 |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.plugin.json` | 发现、配置校验、凭证选项元数据,以及必须在插件代码运行前存在的 UI 提示 |
| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 块 |
| `openclaw.plugin.json` | 设备发现、配置校验、凭证选项元数据,以及必须在插件代码运行前存在的 UI 提示 |
| `package.json` | npm 元数据、依赖安装,以及用于入口点、安装门控、设置或目录元数据的 `openclaw` 配置块 |
如果你不确定某项元数据应放在哪里,请使用这条规则:
如果你不确定某段元数据应放在哪里,请使用以下规则:
- 如果 OpenClaw 必须在加载插件代码之前知道它,就把它放到 `openclaw.plugin.json`
- 如果它与打包、入口文件或 npm 安装行为有关,就把它放到 `package.json`
- 如果 OpenClaw 必须在加载插件代码之前知道它,就放入 `openclaw.plugin.json`
- 如果它与打包、入口文件或 npm 安装行为有关,就放入 `package.json`
### 影响发现的 `package.json` 字段
### 影响设备发现的 `package.json` 字段
某些运行时前插件元数据有意放在 `package.json``openclaw` 块下,而不是 `openclaw.plugin.json` 中。
某些运行时前插件元数据有意放在 `package.json``openclaw` 配置块下,而不是 `openclaw.plugin.json` 中。
重要示例:
| 字段 | 含义 |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `openclaw.extensions` | 声明原生插件入口点。必须保持在插件包目录内。 |
| `openclaw.runtimeExtensions` | 为已安装包声明构建的 JavaScript 运行时入口点。必须保持在插件包目录内。 |
| `openclaw.setupEntry` | 仅用于设置的轻量级入口点,用于 onboarding、延迟的渠道启动以及只读的渠道状态 / SecretRef 发现。必须保持在插件包目录内。 |
| `openclaw.runtimeSetupEntry` | 为已安装包声明构建的 JavaScript 设置入口点。必须保持在插件包目录内。 |
| `openclaw.channel` | 低开销的渠道目录元数据,例如标签、文档路径、别名和选择文案。 |
| `openclaw.channel.configuredState` | 轻量级已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅环境变量驱动的设置?”。 |
| `openclaw.channel.persistedAuthState` | 轻量级持久化凭证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已有任何内容完成登录?”。 |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 用于内置插件和外部发布插件的安装 / 更新提示。 |
| `openclaw.runtimeExtensions` | 为已安装包声明构建的 JavaScript 运行时入口点。必须保持在插件包目录内。 |
| `openclaw.setupEntry` | 在 onboarding、延后渠道启动和只读渠道状态 / SecretRef 发现期间使用的轻量级仅设置入口点。必须保持在插件包目录内。 |
| `openclaw.runtimeSetupEntry` | 为已安装包声明构建的 JavaScript 设置入口点。必须保持在插件包目录内。 |
| `openclaw.channel` | 轻量级渠道目录元数据,例如标签、文档路径、别名和选择说明文本。 |
| `openclaw.channel.configuredState` | 轻量级已配置状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已存在仅环境变量的设置?”。 |
| `openclaw.channel.persistedAuthState` | 轻量级持久化凭证状态检查器元数据,可在不加载完整渠道运行时的情况下回答“是否已有任何内容登录?”。 |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 内置和外部发布插件的安装 / 更新提示。 |
| `openclaw.install.defaultChoice` | 当有多个安装来源可用时的首选安装路径。 |
| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 宿主版本,使用类似 `>=2026.3.22` 的 semver 下限。 |
| `openclaw.install.expectedIntegrity` | 预期的 npm 分发完整性字符串,例如 `sha512-...`;安装和更新流程会据此校验获取的制品。 |
| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许使用一个范围很窄的内置插件重装恢复路径。 |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许在启动期间,先加载仅设置用的渠道表面,再加载完整渠道插件。 |
| `openclaw.install.minHostVersion` | 最低支持的 OpenClaw 宿主版本,使用`>=2026.3.22` 这样的 semver 下限。 |
| `openclaw.install.expectedIntegrity` | 预期的 npm 分发完整性字符串,例如 `sha512-...`;安装和更新流程会据此校验获取的制品。 |
| `openclaw.install.allowInvalidConfigRecovery` | 当配置无效时,允许一个范围很窄的内置插件重装恢复路径。 |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 允许仅设置的渠道界面在启动期间于完整渠道插件之前加载。 |
清单元数据决定了在运行时加载前,onboarding 中会出现哪些 provider / 渠道 / 设置选项。`package.json#openclaw.install` 告诉 onboarding当用户选择其中某个选项时如何获取或启用该插件。不要将安装提示移到 `openclaw.plugin.json`
清单元数据决定了在运行时加载前,哪些提供商 / 渠道 / 设置选项会出现在 onboarding 中。`package.json#openclaw.install` 告诉 onboarding当用户选择这些选项之一时应如何获取或启用该插件。不要将安装提示移入 `openclaw.plugin.json`
`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;较新但有效的值会使插件在较旧宿主上被跳过。
`openclaw.install.minHostVersion` 会在安装和清单注册表加载期间强制执行。无效值会被拒绝;较新的但有效的值会让插件在较旧宿主上被跳过。
精确的 npm 版本固定已存在于 `npmSpec` 中,例如
`"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确 spec 与 `expectedIntegrity` 配对使用,这样如果获取到的 npm 制品不再匹配固定发布版本,更新流程就会失败关闭。为兼容起见,交互式 onboarding 仍会提供受信任注册表的 npm spec包括裸包名和 dist-tag。目录诊断可以区分精确、浮动、带完整性固定、缺失完整性以及无效默认选项来源。它们还会在存在 `expectedIntegrity` 但没有可用于固定它的有效 npm 来源时发出警告。当存在 `expectedIntegrity` 时,安装 / 更新流程会强制执行它;当省略时,注册表解析结果会被记录,但不带完整性固定。
精确 npm 版本固定已存在于 `npmSpec` 中,例如 `"npmSpec": "@wecom/wecom-openclaw-plugin@1.2.3"`。官方外部目录条目应将精确版本说明与 `expectedIntegrity` 搭配使用,这样如果获取到的 npm 制品不再匹配已固定的发布版本,更新流程就会采用失败即关闭的策略。为保持兼容性,交互式 onboarding 仍会提供受信任注册表中的 npm 说明,包括裸包名和 dist-tag。目录诊断可以区分精确、浮动、带完整性固定、缺少完整性、包名不匹配以及无效默认选项来源。它们还会在存在 `expectedIntegrity` 但没有可供固定的有效 npm 来源时发出警告。当存在 `expectedIntegrity` 时,安装 / 更新流程会强制执行它;当其缺失时,注册表解析结果会被记录,但不带完整性固定。
当状态、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`。该设置入口应公开渠道元数据,以及适用于设置阶段的配置、状态和 secrets 适配器将网络客户端、Gateway 网关 监听器和传输运行时保留在主扩展入口点中。
当状态、渠道列表或 SecretRef 扫描需要在不加载完整运行时的情况下识别已配置账户时,渠道插件应提供 `openclaw.setupEntry`。该设置入口点应暴露渠道元数据以及适用于设置阶段的配置、状态和密钥适配器网络客户端、Gateway 网关监听器和传输运行时应保留在主扩展入口点中。
运行时入口点字段不会覆盖源入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变可加载。
运行时入口点字段不会覆盖源入口点字段的包边界检查。例如,`openclaw.runtimeExtensions` 不能让一个越界的 `openclaw.extensions` 路径变可加载。
`openclaw.install.allowInvalidConfigRecovery` 的设计范围是刻意受限的。它不会让任意损坏的配置变得可安装。当前它只允许安装流程从特定的陈旧内置插件升级失败中恢复,例如缺失的内置插件路径,或同一内置插件的陈旧 `channels.<id>` 条目。无关的配置错误仍会阻止安装,并引导操作人员运行 `openclaw doctor --fix`
`openclaw.install.allowInvalidConfigRecovery` 的设计范围是刻意收窄的。它不会让任意损坏的配置变得可安装。目前,它只允许安装流程从特定的陈旧内置插件升级失败中恢复,例如缺失的内置插件路径,或同一内置插件对应的陈旧 `channels.<id>` 条目。无关的配置错误仍会阻止安装,并将操作人员引导到 `openclaw doctor --fix`
`openclaw.channel.persistedAuthState` 是一个微型检查器模块的包元数据:
@ -550,9 +550,9 @@ OpenClaw 按以下优先级应用:
}
```
当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前进行廉价的“是 / 否”凭证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 转发它。
当设置、Doctor 或已配置状态流程需要在完整渠道插件加载前进行一个低成本的“是 / 否”凭证探测时,请使用它。目标导出应是一个只读取持久化状态的小函数;不要通过完整渠道运行时 barrel 暴露它。
`openclaw.channel.configuredState`仅由环境变量驱动的低开销配置检查采用相同的结构:
`openclaw.channel.configuredState`于低成本的仅环境变量已配置检查,遵循相同的结构:
```json
{
@ -568,54 +568,51 @@ OpenClaw 按以下优先级应用:
}
```
渠道可以仅根据环境变量或其他微型非运行时输入回答配置状态时,请使用它。如果该检查需要完整配置解析或真实渠道运行时,请改为将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
某个渠道可以根据环境变量或其他微小的非运行时输入来回答已配置状态时,请使用它。如果检查需要完整配置解析或真实的渠道运行时,请将该逻辑保留在插件 `config.hasConfiguredState` hook 中。
## 发现优先级(重复插件 id
## 设备发现优先级(重复插件 id
OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、配置中显式选定的路径)。如果两个发现结果共享同一个 `id`,则只保留**优先级最高**的清单;优先级较低的重复项会被丢弃,而不会与之并行加载。
OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区、配置中显式选定的路径)。如果两个发现结果共享相同的 `id`,则只保留**优先级最高**的清单;较低优先级的重复项会被丢弃,而不是与其并行加载。
优先级从高到低如下:
1. **配置选定** —— 在 `plugins.entries.<id>` 中显式固定的路径
2. **内置** —— 随 OpenClaw 一起发的插件
2. **内置** —— 随 OpenClaw 一起发的插件
3. **全局安装** —— 安装到全局 OpenClaw 插件根目录中的插件
4. **工作区** —— 相对于当前工作区发现的插件
影响:
- 放在工作区中某个内置插件分叉版或陈旧副本,不会遮蔽内置构建版本。
- 如果确实要用本地插件覆盖内置插件,请通过 `plugins.entries.<id>` 固定它,让它凭优先级获胜,而不要依赖工作区发现。
- 被丢弃的重复项会记录日志,以便 Doctor 和启动诊断能指出被舍弃的副本。
- 工作区中某个内置插件分叉版或陈旧副本,不会遮蔽内置构建版本。
- 如果你确实想用本地插件覆盖一个内置插件,请通过 `plugins.entries.<id>` 固定它,使其凭优先级胜出,而不是依赖工作区发现。
- 被丢弃的重复项会记录日志,以便 Doctor 和启动诊断能指出被舍弃的副本。
## JSON Schema 要求
- **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置。
- 空 schema 是可接受的(例如 `{ "type": "object", "additionalProperties": false }`)。
- schema 会在配置读写时校验,而不是在运行时校验。
- **每个插件都必须提供一个 JSON Schema**,即使它不接受任何配置也是如此
- 空 schema 是可接受的(例如 `{ "type": "object", "additionalProperties": false }`)。
- Schema 会在配置读 / 写时校验,而不是在运行时校验。
## 校验行为
- 未知的 `channels.*` 键是**错误**,除非该渠道 id 已由某个插件清单声明。
- `plugins.entries.<id>`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*`
必须引用**可发现的**插件 id。未知 id 属于**错误**。
- 如果某个插件已安装,但它的清单或 schema 缺失或已损坏,
校验会失败,并且 Doctor 会报告该插件错误。
- 如果插件配置存在,但该插件**已禁用**,配置会被保留,并且
Doctor + 日志中会显示一条**警告**。
- 未知的 `channels.*` 键会被视为**错误**,除非该渠道 id 由某个插件清单声明。
- `plugins.entries.<id>`、`plugins.allow`、`plugins.deny` 和 `plugins.slots.*` 必须引用**可发现的**插件 id。未知 id 会被视为**错误**。
- 如果某个插件已安装,但其清单或 schema 损坏或缺失校验会失败Doctor 会报告该插件错误。
- 如果插件配置存在,但该插件**已禁用**,则配置会被保留,并在 Doctor + 日志中显示**警告**。
完整的 `plugins.*` schema,请参见[配置参考](/zh-CN/gateway/configuration)。
完整的 `plugins.*` schema 请参阅 [配置参考](/zh-CN/gateway/configuration)。
## 说明
- 对于**原生 OpenClaw 插件**,清单是**必需的**,包括本地文件系统加载。运行时仍会单独加载插件模块;清单仅用于发现 + 校验。
- 原生清单使用 JSON5 解析,因此允许注释、尾随逗号和未加引号的键,只要最终值仍是一个对象即可。
- 清单加载器只会读取文档说明的清单字段。避免使用自定义顶层键。
- 当插件不需要它们时,可以省略 `channels`、`providers`、`cliBackends` 和 `skills`
- `providerDiscoveryEntry` 必须保持轻量,不应导入宽泛的运行时代码;应将其用于静态 provider 目录元数据或窄范围发现描述符,而不是请求时执行。
- 互斥插件类型通过 `plugins.slots.*` 选择:`kind: "memory"` 对应 `plugins.slots.memory``kind: "context-engine"` 对应 `plugins.slots.contextEngine`(默认值为 `legacy`)。
- 环境变量元数据(`providerAuthEnvVars`、`channelEnvVars`)仅具声明性。状态、审计、cron 投递校验以及其他只读表面,在将某个环境变量视为已配置之前,仍会应用插件信任和有效激活策略。
- 关于需要 provider 代码的运行时向导元数据,请参见[Provider 运行时 hooks](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
- 如果你的插件依赖原生模块,请记录构建步骤以及任何包管理器允许列表要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild <package>`)。
- **原生 OpenClaw 插件必须提供清单**,包括本地文件系统加载。运行时仍会单独加载插件模块;清单仅用于发现 + 校验。
- 原生清单使用 JSON5 解析,因此支持注释、尾随逗号和不带引号的键,只要最终值仍然是一个对象即可。
- 清单加载器只会读取文档说明的清单字段。避免使用自定义顶层键。
- 当插件不需要时,`channels`、`providers`、`cliBackends` 和 `skills` 都可以省略
- `providerDiscoveryEntry` 必须保持轻量,不应导入宽泛的运行时代码;应将其用于静态提供商目录元数据或窄范围发现描述符,而不是请求期执行。
- 互斥插件类型通过 `plugins.slots.*` 选择:`kind: "memory"` 对应 `plugins.slots.memory``kind: "context-engine"` 对应 `plugins.slots.contextEngine`(默认 `legacy`)。
- 环境变量元数据(`providerAuthEnvVars`、`channelEnvVars`)仅为声明式信息。状态、审计、cron 递送校验及其他只读界面,在将环境变量视为已配置之前,仍会应用插件信任与有效激活策略。
- 关于需要提供商代码的运行时向导元数据,请参阅 [提供商运行时 hooks](/zh-CN/plugins/architecture-internals#provider-runtime-hooks)。
- 如果你的插件依赖原生模块,请记录构建步骤以及所有包管理器允许列表要求(例如 pnpm `allow-build-scripts` + `pnpm rebuild <package>`)。
## 相关内容
@ -626,7 +623,7 @@ OpenClaw 会从多个根位置发现插件(内置、全局安装、工作区
<Card title="插件架构" href="/zh-CN/plugins/architecture" icon="diagram-project">
内部架构和能力模型。
</Card>
<Card title="SDK 概览" href="/zh-CN/plugins/sdk-overview" icon="book">
<Card title="插件 SDK 概览" href="/zh-CN/plugins/sdk-overview" icon="book">
插件 SDK 参考和子路径导入。
</Card>
</CardGroup>

View File

@ -7,20 +7,20 @@ sidebarTitle: Install and Configure
summary: 安装、配置和管理 OpenClaw 插件
title: 插件
x-i18n:
generated_at: "2026-04-24T15:52:16Z"
generated_at: "2026-04-24T16:35:16Z"
model: gpt-5.4
provider: openai
source_hash: f86476ea9d091271ca1dc925773ee1c32d0a545be5b2f700ebd944b3157881dc
source_hash: d7db42c0c8d7d8b3bddda46a8a42fc19b39b093863b1730b8ca66528a95ecb50
source_path: tools/plugin.md
workflow: 15
---
插件通过新增能扩展 OpenClaw渠道、模型提供商、智能体 harness、工具、Skills、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等等。有些插件属于**核心**插件(随 OpenClaw 一起发布),另一些则属于**外部**插件(由社区发布到 npm
插件通过新增能力来扩展 OpenClaw渠道、模型提供商、智能体 harness、工具、技能、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索等等。有些插件**core**(随 OpenClaw 一起提供),另一些是 **external**(由社区发布到 npm
## 快速开始
<Steps>
<Step title="查看已加载内容">
<Step title="查看已加载内容">
```bash
openclaw plugins list
```
@ -28,10 +28,10 @@ x-i18n:
<Step title="安装插件">
```bash
# From npm
# npm
openclaw plugins install @openclaw/voice-call
# From a local directory or archive
# 从本地目录或归档文件
openclaw plugins install ./my-plugin
openclaw plugins install ./my-plugin.tgz
```
@ -43,12 +43,12 @@ x-i18n:
openclaw gateway restart
```
然后在你的配置文件中,通过 `plugins.entries.\<id\>.config` 进行配置。
然后在你的配置文件中`plugins.entries.\<id\>.config`进行配置。
</Step>
</Steps>
如果你更喜欢以聊天原生方式进行控制,可启用 `commands.plugins: true` 并使用:
如果你更喜欢聊天原生控制,请启用 `commands.plugins: true` 并使用:
```text
/plugin install clawhub:@openclaw/voice-call
@ -56,11 +56,11 @@ x-i18n:
/plugin enable voice-call
```
安装路径使用与 CLI 相同的解析器:本地路径/归档、显式 `clawhub:<pkg>`,或裸包说明符(优先 ClawHub其次回退到 npm
安装路径使用与 CLI 相同的解析器:本地路径/归档文件、显式 `clawhub:<pkg>`,或裸包说明符(优先 ClawHub然后回退到 npm
如果配置无效,安装通常会以安全关闭方式失败,并提示你运行 `openclaw doctor --fix`。唯一的恢复例外,是针对选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件,提供的一条受限内置插件重装路径
如果配置无效,安装通常会以关闭失败的方式结束,并提示你运行 `openclaw doctor --fix`。唯一的恢复例外是一个范围很窄的内置插件重装路径,适用于选择加入 `openclaw.install.allowInvalidConfigRecovery` 的插件。
打包发布的 OpenClaw 安装不会急切安装每个内置插件的完整运行时依赖树。当某个由 OpenClaw 拥有的内置插件因插件配置、旧版渠道配置或默认启用的清单处于活状态时,启动流程只会在导入该插件之前修复声明的运行时依赖。外部插件和自定义加载路径仍然必须通过 `openclaw plugins install` 安装。
打包的 OpenClaw 安装不会急切安装每个内置插件的运行时依赖树。当一个由 OpenClaw 拥有的内置插件通过插件配置、旧版渠道配置或默认启用的清单处于活状态时,启动流程只会在导入该插件之前修复该插件声明的运行时依赖。外部插件和自定义加载路径仍然必须通过 `openclaw plugins install` 安装。
## 插件类型
@ -68,10 +68,10 @@ OpenClaw 可识别两种插件格式:
| 格式 | 工作方式 | 示例 |
| ---------- | ------------------------------------------------------------------ | ------------------------------------------------------ |
| **原生** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 |
| **Bundle** | 与 Codex/Claude/Cursor 兼容的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` |
| **Native** | `openclaw.plugin.json` + 运行时模块;在进程内执行 | 官方插件、社区 npm 包 |
| **Bundle** | 兼容 Codex/Claude/Cursor 的布局;映射到 OpenClaw 功能 | `.codex-plugin/`、`.claude-plugin/`、`.cursor-plugin/` |
两者都会显示在 `openclaw plugins list` 中。有关 Bundle 的详细信息,请参阅 [Plugin Bundles](/zh-CN/plugins/bundles)。
两者都会显示在 `openclaw plugins list` 中。有关 bundle 的详细信息,请参阅 [Plugin Bundles](/zh-CN/plugins/bundles)。
如果你正在编写原生插件,请从 [Building Plugins](/zh-CN/plugins/building-plugins) 和 [插件 SDK 概览](/zh-CN/plugins/sdk-overview) 开始。
@ -81,14 +81,14 @@ OpenClaw 可识别两种插件格式:
| 插件 | 包 | 文档 |
| --------------- | ---------------------- | ------------------------------------ |
| Matrix | `@openclaw/matrix` | [Matrix](/zh-CN/channels/matrix) |
| Microsoft Teams | `@openclaw/msteams` | [Microsoft Teams](/zh-CN/channels/msteams) |
| Nostr | `@openclaw/nostr` | [Nostr](/zh-CN/channels/nostr) |
| Voice Call | `@openclaw/voice-call` | [Voice Call](/zh-CN/plugins/voice-call) |
| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) |
| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) |
| Matrix | `@openclaw/matrix` | [Matrix](/zh-CN/channels/matrix) |
| Microsoft Teams | `@openclaw/msteams` | [Microsoft Teams](/zh-CN/channels/msteams) |
| Nostr | `@openclaw/nostr` | [Nostr](/zh-CN/channels/nostr) |
| Voice Call | `@openclaw/voice-call` | [Voice Call](/zh-CN/plugins/voice-call) |
| Zalo | `@openclaw/zalo` | [Zalo](/zh-CN/channels/zalo) |
| Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/zh-CN/plugins/zalouser) |
### 核心(随 OpenClaw 一起发布
### Core随 OpenClaw 一起提供
<AccordionGroup>
<Accordion title="模型提供商(默认启用)">
@ -99,9 +99,9 @@ OpenClaw 可识别两种插件格式:
`vercel-ai-gateway`, `volcengine`, `xiaomi`, `zai`
</Accordion>
<Accordion title="记忆插件">
- `memory-core` — 内置记忆搜索(默认通过 `plugins.slots.memory` 使用
- `memory-lancedb` — 按需安装的长期记忆,带自动召回/捕获功能(设置 `plugins.slots.memory = "memory-lancedb"`
<Accordion title="Memory 插件">
- `memory-core` — 内置 memory 搜索(默认通过 `plugins.slots.memory`
- `memory-lancedb` — 按需安装的长期 memory带自动召回/捕获(设置 `plugins.slots.memory = "memory-lancedb"`
</Accordion>
<Accordion title="语音提供商(默认启用)">
@ -109,8 +109,8 @@ OpenClaw 可识别两种插件格式:
</Accordion>
<Accordion title="其他">
- `browser` — 用于浏览器工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、浏览器运行时以及默认浏览器控制服务的内置浏览器插件(默认启用;替换前请先禁用)
- `copilot-proxy` — VS Code Copilot Proxy 桥接(默认禁用)
- `browser` — 用于浏览器工具、`openclaw browser` CLI、`browser.request` Gateway 网关方法、浏览器运行时默认浏览器控制服务的内置浏览器插件(默认启用;替换它之前请先禁用)
- `copilot-proxy` — VS Code Copilot Proxy bridge(默认禁用)
</Accordion>
</AccordionGroup>
@ -134,30 +134,30 @@ OpenClaw 可识别两种插件格式:
| 字段 | 描述 |
| ---------------- | --------------------------------------------------------- |
| `enabled` | 主开关(默认:`true` |
| `allow` | 插件允许列表(可选) |
| `deny` | 插件拒绝列表(可选;拒绝优先生效 |
| `load.paths` | 额外的插件文件/目录 |
| `slots` | 独占槽选择器(例如 `memory`、`contextEngine` |
| `enabled` | 主开关(默认:`true` |
| `allow` | 插件允许列表(可选) |
| `deny` | 插件拒绝列表(可选;拒绝优先) |
| `load.paths` | 额外的插件文件/目录 |
| `slots` | 独占槽选择器(例如 `memory`、`contextEngine` |
| `entries.\<id\>` | 每个插件的开关 + 配置 |
配置更改**需要重启 Gateway 网关**。如果 Gateway 网关正在以启用配置监听和进程内重启的方式运行(默认的 `openclaw gateway` 路径),那么在配置写入完成后,通常会自动在短时间内执行重启。对于原生插件运行时代码或生命周期钩子,没有受支持的热重载路径;在你期望更新后的 `register(api)` 代码、`api.on(...)` 钩子、工具、服务或提供商/运行时钩子生效之前,请重启正在为实时渠道提供服务的 Gateway 网关进程。
配置更改 **需要重启 Gateway 网关**。如果 Gateway 网关在启用了配置监视和进程内重启的情况下运行(默认的 `openclaw gateway` 路径),通常会在配置写入后稍等片刻自动执行该重启。对于原生插件运行时代码或生命周期 hook不存在受支持的热重载路径在期待更新后的 `register(api)` 代码、`api.on(...)` hook、工具、服务或提供商/运行时 hook 生效之前,请重启正在服务实时渠道的 Gateway 网关进程。
`openclaw plugins list` 是本地 CLI/配置快照。其中显示为 `loaded` 的插件,表示从该次 CLI 调用所看到的配置/文件来看,该插件可被发现且可被加载。这并不能证明一个已经在运行的远程 Gateway 网关子进程已经重启并加载了相同的插件代码。在 VPS/容器环境且有包装进程的部署中,请将重启信号发送给实际的 `openclaw gateway run` 进程,或对正在运行的 Gateway 网关使用 `openclaw gateway restart`
`openclaw plugins list` 是本地 CLI/配置快照。其中显示为 `loaded` 的插件,表示该插件可从该次 CLI 调用所见的配置/文件中被发现并加载。这并不能证明一个已经运行的远程 Gateway 网关子进程已经重启并加载了同样的插件代码。在 VPS/容器部署中,如果使用了包装进程,请向实际的 `openclaw gateway run` 进程发送重启信号,或者对正在运行的 Gateway 网关使用 `openclaw gateway restart`
<Accordion title="插件状态:已禁用、缺失与无效">
<Accordion title="插件状态:已禁用 vs 缺失 vs 无效">
- **已禁用**:插件存在,但启用规则将其关闭。配置会被保留。
- **缺失**:配置引用了某个插件 id但设备发现未找到它。
- **无效**:插件存在,但其配置不符合声明的 schema
- **缺失**:配置引用了一个插件 id但发现流程没有找到它。
- **无效**:插件存在,但其配置与声明的 schema 不匹配
</Accordion>
## 发现顺序优先级
## 发现顺序优先级
OpenClaw 按以下顺序扫描插件(先匹配者优先):
OpenClaw 按以下顺序扫描插件(先匹配者优先):
<Steps>
<Step title="配置路径">
`plugins.load.paths` — 显式文件或目录路径。
`plugins.load.paths` — 显式文件或目录路径。
</Step>
<Step title="工作区插件">
@ -169,7 +169,7 @@ OpenClaw 会按以下顺序扫描插件(先匹配者优先):
</Step>
<Step title="内置插件">
随 OpenClaw 一起发布。许多默认启用(模型提供商、语音)。
随 OpenClaw 一起提供。许多默认启用(模型提供商、语音)。
其他则需要显式启用。
</Step>
</Steps>
@ -177,74 +177,81 @@ OpenClaw 会按以下顺序扫描插件(先匹配者优先):
### 启用规则
- `plugins.enabled: false` 会禁用所有插件
- `plugins.deny` 始终优先于 allow
- `plugins.deny` 总是优先于 allow
- `plugins.entries.\<id\>.enabled: false` 会禁用该插件
- 来源于工作区的插件**默认禁用**(必须显式启用)
- 来自工作区的插件 **默认禁用**(必须显式启用)
- 内置插件遵循内建的默认启用集合,除非被覆盖
- 独占槽位可强制启用该槽位所选中的插件
- 独占插槽可以强制启用为该插槽选定的插件
- 某些选择加入的内置插件会在配置命名了某个插件拥有的表面时自动启用,例如提供商模型引用、渠道配置或 harness 运行时
- OpenAI 系列的 Codex 路由保持独立的插件边界:
`openai-codex/*` 属于 OpenAI 插件,而内置的 Codex
app-server 插件则 `embeddedHarness.runtime: "codex"` 或旧版
app-server 插件则通过 `embeddedHarness.runtime: "codex"` 或旧版
`codex/*` 模型引用来选择
## 运行时钩子故障排除
## 运行时 hook 故障排除
如果某个插件出现在 `plugins list` 中,但它的 `register(api)` 副作用或钩子没有在实时聊天流量中运行,请先检查以下内容:
如果某个插件出现在 `plugins list` 中,但 `register(api)` 副作用或 hook 没有在实时聊天流量中运行,请先检查以下内容:
- 运行 `openclaw gateway status --deep --require-rpc`,并确认当前生效的 Gateway 网关 URL、profile、配置路径和进程就是你正在编辑的那些。
- 在插件安装/配置/代码变更后,重启实时 Gateway 网关。在包装容器中PID 1 可能只是一个 supervisor请重启或发送信号给子进程 `openclaw gateway run`
- 使用 `openclaw plugins inspect <id> --json` 确认钩子注册和诊断信息。像 `llm_input`、`llm_output` 和 `agent_end` 这样的非内置会话钩子,需要
- 运行 `openclaw gateway status --deep --require-rpc`,并确认活动的
Gateway 网关 URL、profile、配置路径和进程就是你正在编辑的那些。
- 在插件安装/配置/代码更改后,重启正在运行的 Gateway 网关。在包装容器中,
PID 1 可能只是一个 supervisor请重启或向子进程
`openclaw gateway run` 发送信号。
- 使用 `openclaw plugins inspect <id> --json` 确认 hook 注册和
诊断信息。像 `llm_input`
`llm_output``agent_end` 这样的非内置会话 hook需要
`plugins.entries.<id>.hooks.allowConversationAccess=true`
- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体回合进行模型解析之前运行;`llm_output` 只有在某次模型尝试产生助手输出后才会运行。
- 若要证明实际生效的会话模型,请使用 `openclaw sessions` 或 Gateway 网关的会话/状态相关表面;在调试提供商负载时,可使用 `--raw-stream --raw-stream-path <path>` 启动 Gateway 网关。
- 对于模型切换,优先使用 `before_model_resolve`。它会在智能体轮次的模型解析之前运行;`llm_output` 只会在一次模型尝试生成 assistant 输出之后运行。
- 如需证明实际生效的会话模型,请使用 `openclaw sessions`
Gateway 网关的会话/状态表面;调试提供商 payload 时,请使用
`--raw-stream --raw-stream-path <path>` 启动 Gateway 网关。
## 插件槽位(独占类别)
## 插件 slots(独占类别)
某些类别是独占的(同一时间只能激活一个):
某些类别是独占的(一次只能激活一个):
```json5
{
plugins: {
slots: {
memory: "memory-core", // or "none" to disable
contextEngine: "legacy", // or a plugin id
memory: "memory-core", // 或使用 "none" 来禁用
contextEngine: "legacy", // 或一个插件 id
},
},
}
```
| 槽 | 控制内容 | 默认值 |
| 槽 | 控制内容 | 默认值 |
| --------------- | --------------------- | ------------------- |
| `memory` | 活跃的记忆插件 | `memory-core` |
| `contextEngine` | 活的上下文引擎 | `legacy`(内建) |
| `memory` | 活动的 memory 插件 | `memory-core` |
| `contextEngine` | 活的上下文引擎 | `legacy`(内建) |
## CLI 参考
```bash
openclaw plugins list # compact inventory
openclaw plugins list --enabled # only loaded plugins
openclaw plugins list --verbose # per-plugin detail lines
openclaw plugins list --json # machine-readable inventory
openclaw plugins inspect <id> # deep detail
openclaw plugins inspect <id> --json # machine-readable
openclaw plugins inspect --all # fleet-wide table
openclaw plugins info <id> # inspect alias
openclaw plugins doctor # diagnostics
openclaw plugins list # 精简清单
openclaw plugins list --enabled # 仅显示已加载的插件
openclaw plugins list --verbose # 每个插件的详细行
openclaw plugins list --json # 机器可读的清单
openclaw plugins inspect <id> # 深度详情
openclaw plugins inspect <id> --json # 机器可读格式
openclaw plugins inspect --all # 全量表格
openclaw plugins info <id> # inspect 别名
openclaw plugins doctor # 诊断
openclaw plugins install <package> # install (ClawHub first, then npm)
openclaw plugins install clawhub:<pkg> # install from ClawHub only
openclaw plugins install <spec> --force # overwrite existing install
openclaw plugins install <path> # install from local path
openclaw plugins install -l <path> # link (no copy) for dev
openclaw plugins install <package> # 安装(优先 ClawHub然后 npm
openclaw plugins install clawhub:<pkg> # 仅从 ClawHub 安装
openclaw plugins install <spec> --force # 覆盖现有安装
openclaw plugins install <path> # 从本地路径安装
openclaw plugins install -l <path> # 链接(不复制),用于开发
openclaw plugins install <plugin> --marketplace <source>
openclaw plugins install <plugin> --marketplace https://github.com/<owner>/<repo>
openclaw plugins install <spec> --pin # record exact resolved npm spec
openclaw plugins install <spec> --pin # 记录精确解析后的 npm 说明符
openclaw plugins install <spec> --dangerously-force-unsafe-install
openclaw plugins update <id-or-npm-spec> # update one plugin
openclaw plugins update <id-or-npm-spec> # 更新单个插件
openclaw plugins update <id-or-npm-spec> --dangerously-force-unsafe-install
openclaw plugins update --all # update all
openclaw plugins uninstall <id> # remove config/install records
openclaw plugins update --all # 更新全部
openclaw plugins uninstall <id> # 删除配置/安装记录
openclaw plugins uninstall <id> --keep-files
openclaw plugins marketplace list <source>
openclaw plugins marketplace list <source> --json
@ -253,31 +260,31 @@ openclaw plugins enable <id>
openclaw plugins disable <id>
```
内置插件随 OpenClaw 一起发布。许多默认启用(例如内置模型提供商、内置语音提供商,以及内置浏览器插件)。其他内置插件仍然需要使用 `openclaw plugins enable <id>`
内置插件随 OpenClaw 一起提供。许多默认启用(例如内置模型提供商、内置语音提供商,以及内置浏览器插件)。其他内置插件仍然需要执行 `openclaw plugins enable <id>`
`--force` 会就地覆盖现有已安装的插件或 hook pack。对于已跟踪的 npm 插件的常规升级,请使用 `openclaw plugins update <id-or-npm-spec>`。该选项不支持与 `--link` 一起使用,因为后者会复用源路径,而不是复制到受管理的安装目标。
`--force` 会就地覆盖一个已安装的插件或 hook 包。对于已跟踪 npm 插件的常规升级,请使用 `openclaw plugins update <id-or-npm-spec>`。该选项不支持与 `--link` 一起使用,因为后者会复用源路径,而不是复制到受管理的安装目标。
`plugins.allow` 已设置时,`openclaw plugins install` 会先将已安装插件的 id 添加到该允许列表中,然后再启用它,因此安装后的插件在重启后即可立即加载。
已经设置了 `plugins.allow` 时,`openclaw plugins install` 会在启用已安装插件之前,将该插件 id 添加到允许列表中,因此重启后安装内容可以立即被加载。
`openclaw plugins update <id-or-npm-spec>` 适用于已跟踪的安装。传入带 dist-tag 或精确版本的 npm 包说明符时,会将包名解析回已跟踪的插件记录,并记录新的说明符以供后续更新使用。传入不带版本的包名时,会将一个精确 pin 的安装恢复到注册表的默认发布线。如果已安装的 npm 插件已经与解析后的版本和记录的产物标识一致OpenClaw 会跳过此次更新,不会下载、重新安装或重写配置。
`openclaw plugins update <id-or-npm-spec>` 适用于已跟踪的安装。传入带 dist-tag 或精确版本的 npm 包说明符时,会将包名解析回已跟踪的插件记录,并为后续更新记录新的说明符。传入不带版本的包名时,会将一个精确固定版本的安装切回注册表的默认发布线。如果已安装的 npm 插件已经与解析后的版本以及记录的构件标识一致OpenClaw 会跳过更新,不会下载、重新安装或重写配置。
`--pin` 仅适用于 npm。不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 源元数据,而不是 npm 说明符。
`--pin` 仅适用于 npm。不支持与 `--marketplace` 一起使用,因为 marketplace 安装会持久化 marketplace 源元数据,而不是 npm 说明符。
`--dangerously-force-unsafe-install` 是一个“破窗”式覆盖选项,用于处理内置危险代码扫描器的误报。它允许插件安装和插件更新在遇到内置 `critical` 级别发现后继续进行,但仍不会绕过插件 `before_install` 策略阻止或扫描失败阻止。
`--dangerously-force-unsafe-install` 是一个用于应对内置危险代码扫描器误报的紧急覆盖开关。它允许插件安装和插件更新在内置 `critical` 级别发现之后继续进行,但仍然不会绕过插件 `before_install` 策略阻止或扫描失败阻止。
CLI 标志仅适用于插件安装/更新流程。由 Gateway 网关支持的 Skills 依赖安装则使用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是独立的 ClawHub Skills 下载/安装流程。
这个 CLI 标志仅适用于插件安装/更新流程。由 Gateway 网关支持的 Skills 依赖安装则用对应的 `dangerouslyForceUnsafeInstall` 请求覆盖,而 `openclaw skills install` 仍然是独立的 ClawHub Skills 下载/安装流程。
兼容的 Bundle 会参与相同的插件 list/inspect/enable/disable 流程。当前运行时支持包括 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` 以及 manifest 声明的 `lspServers` 默认值、Cursor command-skills以及兼容的 Codex hook 目录。
兼容的 bundle 会参与相同的插件 list/inspect/enable/disable 流程。当前运行时支持包括 bundle Skills、Claude command-skills、Claude `settings.json` 默认值、Claude `.lsp.json` 和由清单声明的 `lspServers` 默认值、Cursor command-skills以及兼容的 Codex hook 目录。
`openclaw plugins inspect <id>` 还会报告已检测到的 Bundle 功能,以及由 bundle 支持的或不支持的 MCP 和 LSP server 条目。
`openclaw plugins inspect <id>` 还会报告已检测到的 bundle 能力,以及由 bundle 支持的或不支持的 MCP 和 LSP server 条目。
Marketplace 源可以是来自 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知 marketplace 名称、本地 marketplace 根目录或 `marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL或 git URL。对于远程 marketplace插件条目必须保留在克隆的 marketplace 仓库内,并且只能使用相对路径源。
Marketplace 源可以是 `~/.claude/plugins/known_marketplaces.json` 的 Claude 已知 marketplace 名称、本地 marketplace 根目录或 `marketplace.json` 路径、类似 `owner/repo` 的 GitHub 简写、GitHub 仓库 URL或 git URL。对于远程 marketplace插件条目必须保留在克隆的 marketplace 仓库内,并且只能使用相对路径源。
完整详情请参阅 [`openclaw plugins` CLI 参考](/zh-CN/cli/plugins)。
## 插件 API 概览
原生插件会导出一个暴露 `register(api)` 的入口对象。旧版插件仍可能使用 `activate(api)` 作为旧版别名,但新插件应使用 `register`
原生插件会导出一个暴露 `register(api)` 的入口对象。较旧的插件仍可能使用 `activate(api)` 作为旧版别名,但新插件应使用 `register`
```typescript
export default definePluginEntry({
@ -297,48 +304,48 @@ export default definePluginEntry({
});
```
OpenClaw 会加载该入口对象在插件激活期间调用 `register(api)`对于旧版插件,加载器仍会回退到 `activate(api)`,但内置插件和新的外部插件应将 `register` 视为公共契约。
OpenClaw 会在插件激活期间加载该入口对象并调用 `register(api)`。加载器仍会为旧插件回退到 `activate(api)`,但内置插件和新的外部插件应将 `register` 视为公共契约。
常见注册方法:
| 方法 | 注册内容 |
| --------------------------------------- | --------------------------- |
| `registerProvider` | 模型提供商LLM |
| `registerChannel` | 聊天渠道 |
| `registerTool` | 智能体工具 |
| `registerHook` / `on(...)` | 生命周期钩子 |
| `registerSpeechProvider` | 文本转语音 / STT |
| `registerProvider` | 模型提供商LLM |
| `registerChannel` | 聊天渠道 |
| `registerTool` | 智能体工具 |
| `registerHook` / `on(...)` | 生命周期 hook |
| `registerSpeechProvider` | 文本转语音 / STT |
| `registerRealtimeTranscriptionProvider` | 流式 STT |
| `registerRealtimeVoiceProvider` | 双向实时语音 |
| `registerMediaUnderstandingProvider` | 图像/音频分析 |
| `registerImageGenerationProvider` | 图像生成 |
| `registerMusicGenerationProvider` | 音乐生成 |
| `registerVideoGenerationProvider` | 视频生成 |
| `registerWebFetchProvider` | Web 抓取 / 抓取提供商 |
| `registerWebSearchProvider` | Web 搜索 |
| `registerHttpRoute` | HTTP 端点 |
| `registerCommand` / `registerCli` | CLI 命令 |
| `registerContextEngine` | 上下文引擎 |
| `registerService` | 后台服务 |
| `registerRealtimeVoiceProvider` | 双向实时语音 |
| `registerMediaUnderstandingProvider` | 图像/音频分析 |
| `registerImageGenerationProvider` | 图像生成 |
| `registerMusicGenerationProvider` | 音乐生成 |
| `registerVideoGenerationProvider` | 视频生成 |
| `registerWebFetchProvider` | 网页抓取 / 爬取提供商 |
| `registerWebSearchProvider` | 网页搜索 |
| `registerHttpRoute` | HTTP 端点 |
| `registerCommand` / `registerCli` | CLI 命令 |
| `registerContextEngine` | 上下文引擎 |
| `registerService` | 后台服务 |
类型化生命周期钩子的守卫行为:
类型化生命周期 hook 的 hook guard 行为:
- `before_tool_call``{ block: true }` 为终止性结果;较低优先级的处理器会被跳过
- `before_tool_call``{ block: false }` 是空操作,不会清除先前的阻止。
- `before_install``{ block: true }` 为终止性结果;较低优先级的处理器会被跳过
- `before_install``{ block: false }` 是空操作,不会清除先前的阻止。
- `message_sending``{ cancel: true }` 为终止性结果;较低优先级的处理器会被跳过
- `message_sending``{ cancel: false }` 是空操作,不会清除先前的取消。
- `before_tool_call``{ block: true }` 为终止性结果;会跳过更低优先级的处理器
- `before_tool_call``{ block: false }` 为无操作,不会清除更早的阻止。
- `before_install``{ block: true }` 为终止性结果;会跳过更低优先级的处理器
- `before_install``{ block: false }` 为无操作,不会清除更早的阻止。
- `message_sending``{ cancel: true }` 为终止性结果;会跳过更低优先级的处理器
- `message_sending``{ cancel: false }` 为无操作,不会清除更早的取消。
原生 Codex app-server 会将 bridge Codex-native 工具事件回传到这个钩子表面。插件可以通过 `before_tool_call` 阻止原生 Codex 工具,通过 `after_tool_call` 观察结果,并参与 Codex `PermissionRequest` 审批。该 bridge 目前尚不会重写 Codex-native 工具参数。
原生 Codex app-server 会将 bridge 的 Codex 原生工具事件回传到这个 hook 表面。插件可以通过 `before_tool_call` 阻止原生 Codex 工具,通过 `after_tool_call` 观察结果,并参与 Codex `PermissionRequest` 审批。该 bridge 目前还不会重写 Codex 原生工具参数。
有关完整的类型化钩子行为,请参阅 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。
有关完整的类型化 hook 行为,请参阅 [SDK 概览](/zh-CN/plugins/sdk-overview#hook-decision-semantics)。
## 相关内容
- [Building Plugins](/zh-CN/plugins/building-plugins) — 创建你自己的插件
- [Plugin Bundles](/zh-CN/plugins/bundles) — Codex/Claude/Cursor Bundle 兼容性
- [Plugin Manifest](/zh-CN/plugins/manifest) — manifest schema
- [Plugin Bundles](/zh-CN/plugins/bundles) — Codex/Claude/Cursor bundle 兼容性
- [Plugin Manifest](/zh-CN/plugins/manifest) — 清单 schema
- [Registering Tools](/zh-CN/plugins/building-plugins#registering-agent-tools) — 在插件中添加智能体工具
- [Plugin Internals](/zh-CN/plugins/architecture) — 能力模型加载流水线
- [Plugin Internals](/zh-CN/plugins/architecture) — 能力模型加载流水线
- [Community Plugins](/zh-CN/plugins/community) — 第三方列表