协议
插件清单
Nexting 开发者文档 | 2026 年 8 月
1. 简介
OpenClaw 插件系统允许硬件设备以通道插件的形式接入 OpenClaw AI 平台。每个插件通过清单文件声明其提供的通道以及所需的配置。
Nexting 是硬件通道插件的参考实现——一款可穿戴 AI 语音夹,通过 iPhone 伴侣应用经 BLE 连接到 OpenClaw Gateway。
版本 0.2.0,2026 年 7 月。插件作为 OpenClaw Gateway 进程的一部分运行。
2. 清单格式
每个插件 MUST 在其包根目录下包含一个 openclaw.plugin.json 文件。该清单声明插件身份、提供的通道以及配置的 JSON Schema。
{
"id": "pinclaw",
"channels": ["pinclaw"],
"name": "Nexting",
"description": "Hardware voice interface channel for OpenClaw",
"channelConfigs": {
"pinclaw": {
"schema": {| 字段 | 类型 | 描述 |
|---|---|---|
id | string | 唯一的插件标识符。必须与导出的插件对象的 id 一致。 |
channels | string[] | 该插件提供的通道 ID 列表。每个 ID 将成为 openclaw.json 中 channels.* 下的键。 |
configSchema | object | 描述插件配置结构的 JSON Schema。启动时用于校验。 |
3. 配置 Schema
插件从 openclaw.json 的 channels.pinclaw 部分读取配置。TypeScript 接口定义了可用字段:
interface NextingAccountConfig {
enabled?: boolean; // default: true
wsPort?: number; // default: 18790
authToken?: string; // required for operation
relay?: { // Nexting Cloud relay connection
enabled: boolean;
token: string;
url?: string; // default: wss://api.nexting.ai
};
}| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
enabled | boolean | true | 该账户是否激活。设为 false 可在不删除配置的情况下禁用。 |
wsPort | number | 18790 | 插件的 WebSocket + HTTP 服务器监听端口。 |
authToken | string | (无) | 设备认证的 Bearer Token。缺少此字段时账户将视为未配置。 |
relay | object | (无) | Nexting Cloud 中继连接:{ enabled, token, url? } — url 默认为 wss://api.nexting.ai。 |
单账户配置
最简配置使用一个默认账户。所有字段直接放在 channels.pinclaw 下:
{
"channels": {
"pinclaw": {
"enabled": true,
"wsPort": 18790,
"authToken": "your-secret-token"
}
}
}多账户配置
如需连接多个设备,请使用 accounts 对象。每个键是唯一的账户 ID,每个值是一个 NextingAccountConfig:
{
"channels": {
"pinclaw": {
"accounts": {
"device-1": { "wsPort": 18790, "authToken": "token-1" },
"device-2": { "wsPort": 18791, "authToken": "token-2" }
}
}
}
}accounts 键存在时,插件会遍历其子键来发现账户 ID。当该键不存在时,插件将顶层配置视为一个 ID 为 "default" 的单一账户。4. 适配器
插件暴露五个适配器接口,Gateway 通过它们管理插件生命周期、路由消息和查询状态。
Config 适配器
负责发现账户、解析其完整配置以及报告就绪状态。
| 方法 | 签名 | 描述 |
|---|---|---|
listAccountIds | (cfg) => string[] | 列出所有已配置的账户 ID。从 accounts 键读取,或返回 ["default"]。 |
resolveAccount | (cfg, accountId?) => ResolvedPinclawAccount | 解析完整的账户配置,应用默认值。 |
defaultAccountId | () => string | 返回 "default"。在未指定账户时使用。 |
isConfigured | (account) => boolean | 当 authToken 已设置且非空时返回 true。 |
isEnabled | (account) => boolean | 当 enabled !== false 时返回 true。 |
describeAccount | (account) => object | 返回 { accountId, enabled, configured } 摘要。 |
Outbound 适配器
处理 Agent 到设备的消息投递。当 AI 产生需要发送到硬件设备的响应时,Gateway 会调用 sendText。
| 属性 | 值 |
|---|---|
deliveryMode | "direct" — 插件通过自己的 WebSocket 服务器直接投递到设备。 |
textChunkLimit | 4096 — 每次投递的最大文本长度。 |
sendText 方法路由到 NextingWsServer.sendToDevice()。如果服务器实例不可用(例如启动期间),消息将被丢弃(记录错误日志),sendText 直接返回而不抛出异常。
{ channel: "pinclaw", messageId: string }Status 适配器
跟踪每个账户的运行时状态。Gateway 查询此适配器以在控制面板中展示插件健康状况。
{
accountId: string,
enabled: boolean,
configured: boolean,
running: boolean,
lastError: string | null
}Security 适配器
控制哪些实体可以通过插件通道发送消息。
| 属性 | 值 |
|---|---|
DM Policy | "open" — 任何已认证的设备均可发送消息。 |
allowFrom | ["*"] — 除 Token 认证外无其他发送者限制。 |
allowFromPath 解析为配置树中的 channels.pinclaw.dm.。Gateway 适配器
startAccount 方法是主要的生命周期入口。它作为 Gateway 内的长期运行进程执行:
| 步骤 | 操作 |
|---|---|
| 1 | 创建 NextingWsServer,传入端口、authToken、Gateway URL 和 Gateway Token。 |
| 2 | 启动 HTTP + WebSocket 服务器。 |
| 3 | 通过 WebSocket RPC 连接到 Gateway(Ed25519 认证)。 |
| 4 | 将账户状态设为 running = true。 |
| 5 | 阻塞等待 abort 信号(保持 Gateway 运行)。 |
| 6 | 收到 abort 信号后:停止服务器,将状态置为 running = false。 |
5. 出站投递
从 AI Agent 响应到设备投递的完整消息路由流程:
| 步骤 | 描述 |
|---|---|
| 1 | Agent 产生文本响应。 |
| 2 | Gateway 调用 outbound.sendText()。 |
| 3 | 插件检查目标设备是否有活跃的 WebSocket 连接。 |
| 4 | 已连接:通过 WebSocket 发送 agent_message。 |
| 5 | 离线:插件丢弃该消息(返回 ok:false)。 |
| 6 | 当插件自身离线时,Nexting Cloud 中继将出站消息排队到 Postgres(24 小时 TTL),并在重连时按序投递。 |
6. 工具定义
插件内置三个服务器工具,从 plugin/src/tools/ 自动发现,并作为 <server_tool> 提示工具注入 TOOLS.md。
generate_image
使用 AI 根据文本提示生成图片。
{
"name": "generate_image",
"description": "Generate an image from a text prompt using AI. Returns the image URL that can be displayed to the user via markdown.",
"parameters": {
"prompt": { "type": "string", "required": true, "description": "Detailed English description of the image to generate" },
"size": { "type": "string", "required": false, "description": "\"1024x1024\" (default), \"1792x1024\" (landscape), or \"1024x1792\" (portrait)" }
}
}generate_audio
使用 OpenAI TTS 将文本生成语音音频。
{
"name": "generate_audio",
"description": "Generate speech audio from text using OpenAI TTS. Returns a URL to the audio file.",
"parameters": {
"text": { "type": "string", "required": true, "description": "The text to convert to speech" },
"voice": { "type": "string", "required": false, "description": "\"alloy\" (default), \"echo\", \"fable\", \"onyx\", \"nova\", or \"shimmer\"" },
"speed": { "type": "number", "required": false, "description": "Speed from 0.25 to 4.0 (default 1.0)" }
}
}memory_edit
读取、写入或列出记忆文件。
{
"name": "memory_edit",
"description": "Read, write, or list memory files (~/clawd/memory/*.md).",
"parameters": {
"action": { "type": "string", "required": true, "description": "\"list\", \"read\", \"write\", or \"append\"" },
"filename": { "type": "string", "required": false, "description": "File name, e.g. \"2026-03-11.md\". Required for read/write/append." },
"content": { "type": "string", "required": false, "description": "Content to write or append. Required for write/append." }
}
}device_tools_register WebSocket 消息注册设备工具,Agent 通过 <device_tool> 标签调用它们。调度通过 /cron/jobs REST API 或 cron.* Gateway RPC 进行——不存在 schedule 工具。7. 入站事件
插件通过 WebSocket 连接接收来自客户端的入站事件。主要的入站消息类型:
| 消息类型 | 方向 | 描述 |
|---|---|---|
text | 客户端 → 插件 | 用户输入(通常为 STT 输出),转发至 AI 会话。 |
device_tools_register | 客户端 → 插件 | 手机注册硬件上可用的设备工具。 |
context_update | 客户端 → 插件 | 客户端上下文更新(例如设备状态、语言区域)。 |
8. 权限模型
| 方面 | 策略 |
|---|---|
| Token 认证 | 每个设备账户需要一个 authToken。未携带有效 Token 的连接和 HTTP 请求将被拒绝。 |
| DM 策略 | "open" — 任何已认证的设备均可发送私信。 |
| 速率限制 | 无内置速率限制。依赖 AI 服务商的限额进行成本控制。 |
| WebSocket 认证超时 | 连接后需在 10 秒内完成认证。超时后服务器以代码 4001 关闭连接。 |
| 连接替换 | 来自同一 deviceId 的新连接将替换旧连接。旧的 WebSocket 以代码 1000 关闭。 |
9. 定时任务集成
定时任务通过 Gateway 的 cron 系统将预定消息投递到设备。插件服务器暴露 REST 端点,其 cron-proxy 将 cron.add RPC(announce: true,可选 [DELIVERY:NOTIFY|SILENT|RESULT] 标签前缀)转发到 Gateway。
定时任务端点
| 方法 | 路径 | 描述 |
|---|---|---|
GET | /cron/jobs | 列出所有定时任务。 |
POST | /cron/jobs | 创建新的定时任务。 |
DELETE | /cron/jobs/:id | 按 ID 删除定时任务。 |
POST | /cron/jobs/:id/toggle | 启用或禁用定时任务。 |
创建任务请求
{
"message": "Time to take a break!",
"at": "30m",
"channel": "pinclaw",
"deleteAfterRun": false
}当 channel 为 "pinclaw" 时,cron-proxy 会将 cron.add RPC 转发到 Gateway,并设置 announce: true(可选加 [DELIVERY:NOTIFY|SILENT|RESULT] 标签前缀)。任务在 Gateway 中触发,而不是在插件中。
投递流程
| 步骤 | 描述 |
|---|---|
| 1 | 定时任务在预定时间在 Gateway 中触发。 |
| 2 | announce 管线将结果路由到 pinclaw 通道。 |
| 3 | Gateway 调用 outbound.sendText(),路由到 sendToDevice()。 |
| 4 | 若设备在线:通过 WebSocket 投递。 |
| 5 | 若设备离线:消息被丢弃。若插件自身离线,Nexting Cloud 中继将消息排队到 Postgres(24 小时 TTL),并在重连时投递。 |
10. 生命周期钩子
startAccount(ctx)
主要的生命周期钩子。Gateway 为每个已启用且已配置的账户调用此方法。上下文对象提供:
| 属性 | 类型 | 描述 |
|---|---|---|
ctx.account | ResolvedPinclawAccount | 完全解析的账户配置,已应用默认值。 |
ctx.cfg | object | 完整的 OpenClaw 配置(openclaw.json)。 |
ctx.log | Logger | 带有 info、warn、error 方法的作用域日志器。 |
ctx.abortSignal | AbortSignal | 当 Gateway 请求关闭时触发。 |
ctx.setStatus | function | 更新此账户的运行时状态。 |
启动流程
1. Read gateway port from ctx.cfg.gateway.port (default: 18789)
2. Read gateway token from ctx.cfg.gateway.auth.token
3. Create NextingWsServer instance
4. Call server.start()
5. Connect Gateway WebSocket RPC (Ed25519 auth)
6. Set status: running = true
7. Await abort signal (blocks — keeps gateway alive)
8. On abort: server.stop(), running = falseGateway 自动重连
如果 Gateway WebSocket 断开连接,插件将在 3 秒延迟后自动重连。这确保 RPC 通道能从瞬态网络问题中恢复,无需手动干预。
stop() 钩子——关闭完全通过 AbortSignal 处理。当信号触发时,服务器停止,WebSocket 连接关闭,状态设为 running = false。