协议

插件清单

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。

openclaw.plugin.json57 lines
{
  "id": "pinclaw",
  "channels": ["pinclaw"],
  "name": "Nexting",
  "description": "Hardware voice interface channel for OpenClaw",
  "channelConfigs": {
    "pinclaw": {
      "schema": {
字段类型描述
idstring唯一的插件标识符。必须与导出的插件对象的 id 一致。
channelsstring[]该插件提供的通道 ID 列表。每个 ID 将成为 openclaw.json 中 channels.* 下的键。
configSchemaobject描述插件配置结构的 JSON Schema。启动时用于校验。

3. 配置 Schema

插件从 openclaw.json 的 channels.pinclaw 部分读取配置。TypeScript 接口定义了可用字段:

NextingAccountConfig (from types.ts)
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
  };
}
字段类型默认值描述
enabledbooleantrue该账户是否激活。设为 false 可在不删除配置的情况下禁用。
wsPortnumber18790插件的 WebSocket + HTTP 服务器监听端口。
authTokenstring(无)设备认证的 Bearer Token。缺少此字段时账户将视为未配置。
relayobject(无)Nexting Cloud 中继连接:{ enabled, token, url? } — url 默认为 wss://api.nexting.ai。

单账户配置

最简配置使用一个默认账户。所有字段直接放在 channels.pinclaw 下:

openclaw.json — single account
{
  "channels": {
    "pinclaw": {
      "enabled": true,
      "wsPort": 18790,
      "authToken": "your-secret-token"
    }
  }
}

多账户配置

如需连接多个设备,请使用 accounts 对象。每个键是唯一的账户 ID,每个值是一个 NextingAccountConfig:

openclaw.json — multi-account
{
  "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 服务器直接投递到设备。
textChunkLimit4096 — 每次投递的最大文本长度。

sendText 方法路由到 NextingWsServer.sendToDevice()。如果服务器实例不可用(例如启动期间),消息将被丢弃(记录错误日志),sendText 直接返回而不抛出异常。

sendText return shape
{ channel: "pinclaw", messageId: string }

Status 适配器

跟踪每个账户的运行时状态。Gateway 查询此适配器以在控制面板中展示插件健康状况。

Account status snapshot
{
  accountId: string,
  enabled: boolean,
  configured: boolean,
  running: boolean,
  lastError: string | null
}

Security 适配器

控制哪些实体可以通过插件通道发送消息。

属性值
DM Policy"open" — 任何已认证的设备均可发送消息。
allowFrom["*"] — 除 Token 认证外无其他发送者限制。
所有持有有效 Token 的设备均可发送消息。基于 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 响应到设备投递的完整消息路由流程:

步骤描述
1Agent 产生文本响应。
2Gateway 调用 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 根据文本提示生成图片。

generate_image
{
  "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 将文本生成语音音频。

generate_audio
{
  "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

读取、写入或列出记忆文件。

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启用或禁用定时任务。

创建任务请求

POST /cron/jobs
{
  "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 中触发。
2announce 管线将结果路由到 pinclaw 通道。
3Gateway 调用 outbound.sendText(),路由到 sendToDevice()。
4若设备在线:通过 WebSocket 投递。
5若设备离线:消息被丢弃。若插件自身离线,Nexting Cloud 中继将消息排队到 Postgres(24 小时 TTL),并在重连时投递。

10. 生命周期钩子

startAccount(ctx)

主要的生命周期钩子。Gateway 为每个已启用且已配置的账户调用此方法。上下文对象提供:

属性类型描述
ctx.accountResolvedPinclawAccount完全解析的账户配置,已应用默认值。
ctx.cfgobject完整的 OpenClaw 配置(openclaw.json)。
ctx.logLogger带有 info、warn、error 方法的作用域日志器。
ctx.abortSignalAbortSignal当 Gateway 请求关闭时触发。
ctx.setStatusfunction更新此账户的运行时状态。

启动流程

startAccount execution flow
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 = false

Gateway 自动重连

如果 Gateway WebSocket 断开连接,插件将在 3 秒延迟后自动重连。这确保 RPC 通道能从瞬态网络问题中恢复,无需手动干预。

插件作为 Gateway 内的长期运行进程运行。它没有单独的 stop() 钩子——关闭完全通过 AbortSignal 处理。当信号触发时,服务器停止,WebSocket 连接关闭,状态设为 running = false。