npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@massapi/openclaw-channel

v1.0.10

Published

`openclaw-msghub` 是一个 OpenClaw channel plugin,用来把本地 MsgHub 的 SSE 事件流和响应接口接入 OpenClaw。

Readme

openclaw-msghub

openclaw-msghub 是一个 OpenClaw channel plugin,用来把本地 MsgHub 的 SSE 事件流和响应接口接入 OpenClaw。

当前实现的 channel id 为 msghub,面向一对一会话(chatTypes: ["direct"]),支持流式 block 回复。

1. 接入目标

插件负责两件事:

  1. 从 MsgHub 的 SSE 事件接口持续接收入站消息。
  2. 将 OpenClaw 生成的回复通过 MsgHub 的响应接口回写。

对应实现:

2. Channel 接入规范

本实现遵循 OpenClaw channel plugin 的基本约定:

  • 使用 defineChannelPluginEntry(...) 暴露插件入口。
  • 使用 createChatChannelPlugin(...) 定义 channel 能力。
  • 通过 configSchema + config adapter 暴露配置面。
  • 通过 gateway.startAccount(...) 建立长连接接收入站事件。
  • 通过 outbound.attachedResults.sendText/sendMedia(...) 发送出站回复。
  • 通过 runInboundReplyTurn(...) 把外部消息转成 OpenClaw 标准 agent turn。

代码里已经包含 OpenClaw 的契约测试:

其中使用了 expectChannelPluginContract(...) 校验基础 channel contract。

3. MsgHub 协议

3.1 入站事件

插件通过下面的 SSE 接口订阅消息:

GET /api/agent/events?access_token=<AGENT_TOKEN>
Accept: text/event-stream

默认基地址是:

http://127.0.0.1:8787

完整 URL 由 eventsUrl 生成,当前实现把 token 放在 query string:

http://127.0.0.1:8787/api/agent/events?access_token=...

SSE data: 中的 JSON 事件结构为:

{
  "requestId": "request_xxx",
  "message": {
    "id": "msg_xxx",
    "sender": "alice",
    "senderName": "Alice",
    "contentType": "text/markdown",
    "data": "hello",
    "createdAt": "1777892405"
  }
}

字段语义:

  • requestId: 本次请求的关联 id;插件回复时原样带回。
  • message.id: 上游消息 id。
  • message.sender: 对端标识;当前实现将它映射为 direct peer id。
  • message.senderName: 展示名,可选。
  • message.contentType: 当前设计使用 text/markdown
  • message.data: 实际消息体。
  • message.createdAt: 可选 Unix 时间戳字符串(秒级,如 "1777892405";毫秒级数值 "1777892405123" 同样接受),插件统一转成毫秒时间。为向后兼容,ISO 8601 字符串仍可解析。

3.2 入站消息文本提取规则

extractTextFromEvent 的处理规则是:

  • contentType === "text/markdown",直接把 data 当消息文本。
  • contentType === "application/json",先尝试 JSON.parse。
  • 解析成功后,按 textmessagecontentprompt 的优先顺序提取字符串字段。
  • 如果 JSON 解析失败,或没有命中这些字段,则回退为原始 data

3.3 去重策略

同一账号的 SSE 事件流只保留相邻不重复的消息:

  • 对每一条入站事件,计算 message.data 的 SHA-256 hash。
  • 仅当 hash 与「上一条已处理消息」的 hash 不同才会分发给 agent;否则被判为相邻重复消息。
  • 对相邻重复消息,插件直接通过 POST /api/agent/respond 回复 "重复请求",不再进入 agent turn 流程。
  • 比较只针对相邻消息,不再基于时间窗口;A B A 序列中的第二个 A 仍会被处理。
  • 连接断开并重连后,缓存会随账号网关重新初始化,首条消息一定会被处理。

实现见 shouldProcessMsgHubEventhashMsgHubDataMSGHUB_DUPLICATE_REPLY_TEXT

3.4 出站响应

插件通过下面的接口回写响应:

POST /api/agent/respond
Authorization: Bearer <AGENT_TOKEN>
Content-Type: application/json

请求体结构:

{
  "requestId": "request_xxx",
  "response": {
    "sender": "Local Hub",
    "senderName": "Local Hub",
    "contentType": "text/markdown",
    "data": "done"
  }
}

对应生成逻辑在:

编码规则:

  • contentType 固定为 text/markdown
  • data 直接发送 OpenClaw 生成的回复文本。
  • sendersenderName 统一使用账号配置里的 name

4. OpenClaw 内部映射

当前实现把 MsgHub 事件映射成 OpenClaw 的 direct chat turn:

  • agentId: 固定为 default
  • channel: msghub
  • peer.id: message.sender
  • To / OriginatingTo: requestId
  • MessageSid: message.id
  • SenderName: message.senderName ?? message.sender

关键逻辑见 handleMsgHubEvent

这意味着:

  • 同一个 sender 会被视为同一个 direct peer。
  • 回复线程关联依赖 requestId
  • 当前没有群聊、多线程、多 agent 路由扩展。

5. 配置规范

插件读取 channels.msghub 配置段,默认账号 id 为 default

支持的字段见 msgHubConfigSchema

{
  "channels": {
    "msghub": {
      "enabled": true,
      "name": "Local Hub",
      "baseUrl": "http://127.0.0.1:8787",
      "accessToken": "token-1",
      "allowFrom": ["alice"],
      "dmPolicy": "open"
    }
  }
}

说明:

  • baseUrl 默认值:http://127.0.0.1:8787
  • accessToken 也可通过环境变量 MSGHUB_ACCESS_TOKEN 提供
  • sender / senderName 不再单独配置,统一使用 name
  • contentType 固定为 text/markdown
  • dmPolicy 支持:openallowlistdisabledpairing

也支持多账号形式:

{
  "channels": {
    "msghub": {
      "accessToken": "token-default",
      "accounts": {
        "dev": {
          "baseUrl": "http://127.0.0.1:8788",
          "accessToken": "token-dev"
        }
      }
    }
  }
}

6. 兼容性结论

截至 2026-05-04,我核对了 npm 最新发布版本,openclaw 当前最新版本是 2026.5.2。本仓库的 package.json 依赖也是:

"openclaw": "^2026.5.2"

因此,对“本实现支持最新的 OpenClaw 吗”这个问题,结论是:

是,按当前公开最新版本 [email protected] 看,这个实现就是按该版本 SDK 编写的,并且测试直接依赖这一版的 channel contract helper。

但要区分两个层面:

  1. OpenClaw SDK 兼容性

    • 当前代码使用的 createChatChannelPlugindefineChannelPluginEntryrunInboundReplyTurn、runtime/config adapter 等接口,都来自 [email protected]
    • 只要构建和测试通过,就说明它和这版 SDK 是对齐的。
  2. MsgHub 上游协议兼容性

    • 当前实现假设 SSE 事件结构仍然是 requestId + message{...}
    • 当前实现假设响应接口仍然是 POST /api/agent/respond,并接受 response.sender/senderName/contentType/data
    • 如果 MsgHub 后续修改字段名、鉴权方式、JSON payload 结构或线程语义,代码需要同步调整。

7. 当前实现的边界

已经支持:

  • OpenClaw channel 基础契约
  • direct chat
  • SSE 入站
  • bearer token 出站
  • JSON/纯文本响应编码
  • allowFromdmPolicy

暂未覆盖:

  • 群聊/频道消息
  • richer attachment/media 原生协议
  • 上游自定义复杂 JSON payload 的专用解析
  • 自动重连、退避、心跳监控等更强健的网关策略

8. 验证建议

建议至少验证三件事:

  1. 构建通过:TypeScript 类型与当前 OpenClaw SDK 一致。
  2. 测试通过:基础 channel contract 未破坏。
  3. 联调通过:对真实 MsgHub 的 /api/agent/events/api/agent/respond 完整走通。

8. 测试客户端

仓库内提供了一个独立测试客户端,用来直接验证 MsgHub 服务端的 SSE 长连接和响应接口,不依赖 OpenClaw:

npm run test:client -- --baseUrl http://127.0.0.1:8787 --accessToken <token>

可选参数:

  • --sender <id>: 回写接口里的 response.sender,默认 msghub-test-client
  • --senderName <name>: 回写接口里的 response.senderName,默认与 sender 相同
  • --reconnectMs <ms>: SSE 断开后的重连间隔,默认 3000
  • --compact: 原始收发 JSON 单行打印,默认使用格式化 JSON

行为说明:

  • 连接 GET /api/agent/events?access_token=...
  • 收到消息后,将提取到的文本作为 text/markdowndata 原样回写到 POST /api/agent/respond
  • 打印 [recv:raw] 原始入站事件和 [send:raw] 原始响应请求体
  • message.data 计算 SHA-256 hash,若与上一条相邻消息重复则不再回写原文,而是直接向 POST /api/agent/respond 回复 "重复请求"
  • 如果 SSE 被服务端关闭,会每隔 3 秒重连一次,并在终端输出连接、断开、响应日志

仓库内已有基础测试,联调时重点关注:

  • SSE 是否稳定输出 data: JSON
  • message.contentType 是否为 text/markdown
  • message.data 是否为原始消息文本
  • requestId 是否可直接用于回写响应