DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Ruliu — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
R

dsh-ruliu

Ruliu

百度如流(InfoFlow)↔ DeepSeek Harness 通道插件,支持设置页面配置。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:Hercules-debug/dsh-ruliu#1e73c08c80dd15aa2ebc4c359c7eaa11f10394fe
README兼容性版本

兼容性与来源证明

Ruliu 以 dsh-ruliu 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/17

版本

0.2.0stable
2026/10/17

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
未声明
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/17
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 integrations-communication 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Experimental Plugin Market Bundle@deepseek-ai/dsh-experimental-plugin-market-bundle实验性自定义插件市场:用于浏览和安装来自插件市场索引的捆绑包的“发现”选项卡Ab Wechat Scrapedsh-ab-wechat-scrape--- description: "树外 wechat_scrape 工具:获取微信公众号文章,过滤推广区块,并将每篇文章保存为 Markdown 文件,供此机器的 dsh 配置文件维护者使用。" kind: "package-reference" ---Ab Publishdsh-ab-publish浏览器自动化发布工具,可登录任意网站并发布内容,整合为一个可发布的插件包

README

dsh-ruliu

把**百度如流(InfoFlow)**接到 DeepSeek Harness:在如流里给机器人发消息就能驱动 DSH 会话,DSH 的回复自动回推到如流。

  • 入站:如流开放平台的回调(webhook)模式,注册一个 HTTP 路由接收消息
  • 出站:assistant 的文本回复发回单聊/群聊(群聊带引用回复)
  • 交互:一组斜杠命令(/new /list /use /end /status),命令优先于对话
  • 零额外依赖:只用 node:crypto + 全局 fetch,不需要装官方 SDK

安装

dsh plugin --profile web add /path/to/dsh-ruliu

bundle 默认 enabled: false(不会自己启动)。启用要在 profile 的 cordis.patch.yml 里覆盖配置 —— 见下。

配置

安装并重新加载 DSH 后,在 Web UI 的 设置 → 如流 里填四项:AppKey、AppSecret(如流发给你的应用凭证) 以及 checkToken、AESKey(如流后台「接收消息服务器」里的两个值)。回调地址与注册由插件负责, 点一次「注册回调到如流」即可。

为什么不默认自动生成 Token/AESKey:官方 SDK 的 updateCallbackUrl 确实接受调用方生成的 token / encodingAesKey,但实测在如流后台已经配过「接收消息服务器」的机器人上,接口带过去的 新 AESKey 不一定被消息管道采用 —— 表现是如流推来的消息解不开(webhook 回 500 decryption failed), 而接口不回显落库内容、也没法查询,出问题时很难发现。所以自动生成改成显式开关 autoRegisterCallback(默认 false,在设置页「高级设置」里):只有明确知道这个机器人的密钥 由插件管理时才打开。解密失败时插件会往已知如流会话发一条告警(出站不依赖 AESKey,还发得出去), 不会让你只看到「发消息没反应」。

如果当前 DSH 是已经运行的旧版本,安装新版本后需要让插件重新加载一次;本地 link 开发环境还需要加载仓库里的 settings companion。正常从新版本安装时,客户端设置页面随插件一起加载。

两份客户端产物必须同源:lib/client.js(package.json 的 ./client)和 ui/lib/client.js(link 环境下按 ui/index.mjs 单独挂的 companion)都由 client/settings.cjs 生成,npm run build 会同时写两份,测试里也断言两者字节一致。 只更新其中一份会出现「宿主发的是新版、页面渲染的是旧版」—— 改设置页却看不到效果, 实测踩过一次。

首次安装或无法使用图形设置页时,也可以把 配置模板 合并到 ${DSH_HOME:-$HOME/.dsh}/profiles/web/cordis.patch.yml,但个人凭证不要提交到 GitHub。

找到下面这段,把尖括号里的内容替换成你自己的值:

- id: dsh-ruliu
  config:
    enabled: true
    appKey: '<这里填如流开放平台的 AppKey>'
    appSecret: '<这里填如流开放平台的 AppSecret>'
    agentId: 123456                 # 机器人 Agent ID,只填数字;不需要可以留空
    checkToken: '<如流后台「接收消息服务器」里的 Token>'
    encodingAESKey: '<同一个页面里的 EncodingAESKey,22 位>'
    autoRegisterCallback: false      # true 时上面两项可留空,由插件生成并注册(见上文风险)
    apiHost: 'https://api.im.baidu.com'
    webhookPath: '/dsh-ruliu/webhook'
    publicCallbackUrl: ''           # 留空 = 按浏览器地址/本机内网地址推导
    cwd: '/path/to/your/workspace'
    msgType: 'text'

必须填写的只有两项:

配置项填什么从哪里获取
appKey如流应用 AppKey如流开放平台的应用详情页
appSecret如流应用 AppSecret同一个应用详情页;插件会自动计算接口所需的 md5,不要手动加密

其余都是可选的:

配置项说明
checkToken回调校验 Token。填如流后台「接收消息服务器」里的值;开了 autoRegisterCallback 才可留空
encodingAESKey消息加密 AES Key(22 位 Base64URLSafe)。同上,填后台里的值
agentId机器人 ID。留空时发消息不带 agentid 字段,只影响部分需要它的接口

appKey 和 appSecret 是如流发给你的应用凭证(用来换 app_access_token 发消息); checkToken 和 encodingAESKey 是调用方生成、注册给如流的,所以插件能自动搞定。 不要把真实值提交到 GitHub。

字段必需说明
apiHost可选默认 https://api.im.baidu.com;百度内网机器通常使用 http://apiin.im.baidu.com
webhookPath可选默认 /dsh-ruliu/webhook,要和如流后台填的一致
publicCallbackUrl可选如流服务器能访问到的完整回调地址,例如 http://10.206.116.22:8080/dsh-ruliu/webhook;留空则按「浏览器 origin → DSH_WEB_URL → 本机内网 IPv4」推导
cwd可选新建 DSH 会话的工作目录,改成 DSH 实际运行的目录
msgType可选出站消息类型,text(默认)或 md

机器地址:如流后台「接收消息服务器」里的回调 URL 必须是如流服务器能访问到的地址:

http://<机器内网IP>:8080/dsh-ruliu/webhook

例如 DSH 机器内网 IP 是 10.10.20.35,就填 http://10.10.20.35:8080/dsh-ruliu/webhook。 不能填 127.0.0.1 或 localhost;DSH 不监听 8080 时换成实际端口。

这一段不用手工去如流后台填:设置页点「注册回调到如流」就会把地址 + Token + AESKey 一起 写进机器人后台;首次配置(Token/AESKey 留空)时插件挂载后也会自动注册一次。地址推导顺序是 publicCallbackUrl → 浏览器 origin → DSH_WEB_URL → 探测到的本机内网 IPv4,跳回环和 docker0 之类的虚拟网卡。推导不出来时,在设置页「高级设置 → 对外回调地址」里显式填一个。

如流会先发一次 echostr 校验(插件按 md5(rn + timestamp + checkToken) 验签并原样回显),通过后才开始推消息。

行为

  • 会话映射:一个如流会话(单聊对端 / 群)↔ 一个 DSH 会话,映射存在 <profile>/.dsh-ruliu/sessions.json。首次收到消息时用 ctx.agents.create() 建会话,之后复用。
  • 投递:agent.followup(createUserMessage({...})),即正常的一次用户回合。
  • 回推:订阅 session/event 的 assistant/message,取文本块拼接后发出(群聊带 reply.messageid 做引用回复)。
  • 秒回:回调先回 200 success 再异步处理,避免如流重投。
  • 去重:按消息 id 做 5 分钟窗口去重(如流会重投)。
  • 大整数精度:messageid 超过 2^53-1,插件从解密后的 JSON 原文用正则抠取,不走 JSON.parse。

命令

在如流里直接发(命令优先于对话,都不进模型、不烧 token):

命令作用
/new [提示词]开一个新会话,可带首条提示词
/list(别名 /sessions)列出最近的会话,最多 10 条
/use <序号>(/switch、/resume)把本聊天切到 /list 里的第 N 个会话
/end结束当前绑定,下条消息开新会话
/status看当前绑定的会话与工作目录
/help(/?)显示帮助

/list 的输出长这样:

🗂 **最近的会话**(用 `/use <序号>` 切换)

1. 测试如流与DSH链路
2. 我要做数字人的表情控制,让 ← 当前
3. 8010端口下载文件夹网页

按「最近活跃」排序,不打印时间和活跃标记:排序口径取自 sessionController.list() 的 updatedAt(= max(createdAt, 最后一次用户消息时间)),和 Web 侧边栏完全一致 —— 所以刚从 如流或 Web 任一侧聊过的会话就会排到第 1 条。该服务不可用时退回本插件自己从 session/event 攒的时间戳,再不行才按创建时间。时间和「🟢 活跃」都不打印:IM 是窄屏,这两项会把标题挤到 换行,而「活跃」本来就是排序依据,标出来是冗余信息。

← 当前 标的是本聊天真正绑定的那条会话:如流这边一个聊天只绑一条会话,而 /list 列的是 整个工作区的会话,两者不是一回事。注意只有用户敲进来的消息会推进活跃时间(审批、上下文注入 这类事件不算),所以「我刚点了下这个窗口」不一定等于「这个会话变成最近活跃」。绑定会话如果已经 掉出最近 10 条,/list 会在末尾补一行「当前绑定的是『标题』」,不会让它凭空消失。

列表里不打印 session-<uuid>:那是 DSH 的内部实现细节,IM 里的使用者读不出信息量也用不上 —— 切换靠序号。会话 id 只出现在 <profile>/.dsh-ruliu/log.ndjson 的 command-list / command-use 事件里(command-list 还会带上渲染结果的 preview 和 bound),排查问题时看 日志即可。/status 同理,显示的是会话标题而不是 id。

会话标题:/list 会用 sessionQuery.readTitleSnapshots() 给历史会话补标题(软取, 拿不到就显示 (未命名),不影响主流程)。

已验证 / 未验证

已验证:

  • 协议层(test/protocol.test.mjs,离线自测、按规格自造密文、不需要真实凭证): echostr 验签与回显、错误签名 403、单聊解析、群聊解析、文本块拼接(跳过 AT/replyData)、 大整数 id 精确、重投去重、未知 Content-Type/缺 Encrypt/解密失败的 400/500 分支、非文本消息忽略。
  • 端到端(真实凭证 + 内网如流):test/commands.test.mjs 往活路由注入命令, /help /status /list 的收发、会话映射复用、出站回推均通。
  • 回调注册(test/callback.test.mjs 离线 + 真机各一次):token/AESKey 生成形态、 内网地址选择(跳过 docker0 / link-local)、回调地址推导优先级、updateReCallUrl 的请求体与鉴权头;真机上把配置里的 token/AESKey 清空后,插件自动生成 → 自动注册 (code: "ok")→ 用新密钥收 + 回消息成功,重载后复用 callback.json 里的同一组、 不再重复注册。

未验证:真实报文的字段全貌、群聊 @ 语义、图片/文件消息、websocket 模式。

已知限制(v0.1)

  • 只有 webhook 模式;websocket 模式(官方 SDK,无需公网回调)未实现
  • 没有审批桥:工具调用需要审批时不会推到如流,仍走 Web GUI
  • 不做媒体:图片/语音/文件消息只记日志并忽略
  • 出站只发文本/markdown,不发图片/文件/卡片
  • 一个如流会话同一时刻只绑一个 DSH 会话(用 /use 切,不能并发)

排错

  • 回调 403:checkToken 与如流后台不一致。改过 Token 或换过机器后,点一次设置页的 「注册回调到如流」重新注册(或删掉 <profile>/.dsh-ruliu/callback.json 让插件重新生成并注册)。
  • 回调 500 / decryption failed:encodingAESKey 不对(注意它是 Base64URLSafe,原始 22 位)。
  • 注册失败:日志里看 callback-register 事件的 code / message;常见原因是推导出的回调地址 如流访问不到(填「对外回调地址」),或宿主装了代理导致 apiin.im.baidu.com 走代理返回 502 (把该域名加进代理直连名单)。注册失败不影响 webhook 继续服务,已注册过的机器人照常推消息。
  • 回调 400 unsupported content type:请求没带正确的 Content-Type,或后台推的不是这三种形态。
  • 发消息失败:看 Authorization: Bearer-<token>(连字符)与 code:"ok"(字符串)判定; 出站走的是宿主进程的 fetch,若 api.im.baidu.com 在内网直连而宿主装了代理, 需要把该域名加进代理的直连名单(no_proxy / 插件的 noProxy)。
  • 插件没挂上:enabled: true 且 appKey/appSecret 都非空,否则日志会写 dsh-ruliu: 凭证不全(需要 appKey + appSecret),通道未挂载。
  • 改完代码不生效:profile 的 hmr 行要把插件目录加进 config.root, 否则模块不会被监听(默认只监听 profile 配置)。改完 HMR 直接换模块, 不用重启 dsh(重启会掐断如流这条线)。

实战记录(真实凭证 + 内网环境打通时踩的坑)

按出现顺序,每个都花了一轮排查:

  1. 内联 createUserMessage 时漏了 role: 'user'(最隐蔽的一个) 表现:回合启动、记录 user/message,然后 LLM 调用以 DeepSeek Messages transport failed (code=TRANSPORT) 失败并重试 5 次。 根因:序列化历史时 message.role === undefined → provider 里 previous?.role === wireRole 在首条消息上即成立(undefined === undefined) → 接着读 previous.content 抛 TypeError。 定位方法:给 dsh-llm-deepseek 里 TRANSPORT 包装处临时插一行 console.error 把被包住的 cause 打出来(本次就是这么找到的)。

  2. create 与 resume 都必须显式带 agentOptions(provider/model) 缺模型时回合第一步直接失败。

  3. preset 要组装:agentPresets.resolve → acquireScope → mount (照官方 dsh-webhook 的顺序),否则 agent 的 scoped world 不完整。

  4. sessionPersistence 必须写进 inject:Cordis 对未注入的服务属性直接抛 cannot get property "sessionPersistence" without inject,而 ?. 拦不住属性访问本身。 表现是 /list 恒抛、只剩内存里的活跃会话,持久化的历史一条都列不出来。

  5. 出站请求必须绕过代理:apiin.im.baidu.com 走代理会返回 502。 关键:bypass 列表由代理插件的 noProxy 配置决定,它覆盖启动脚本里的 no_proxy env —— 所以要把 .im.baidu.com,im.baidu.com 写进插件的 noProxy, 只写 env 不够。

  6. WS 模式在本机不可用:端点分配接口返回公网 ws://infoflow-open-gateway.baidu.com/ws(不可达);内网网关 infoflow-open-gateway.weiyun.baidu.com 只服务端点分配、不服务 WS (/ws、/open/ws、/open/ws/connect、/im/ws 全 404);走代理握手被掐。 ⇒ 只能用 webhook 模式。

排障入口:<profile>/.dsh-ruliu/log.ndjson —— 插件自己写的结构化日志, 每行 {at, event, detail},覆盖 mounted / webhook-hit / inbound / agent-options-resolved / preset-composed / session-created|resumed|reused / followup-delivered|failed / turn-end / outbound-attempt|sent|failed。

注:命令类回复(/list、/status …)走的是 client.sendText,不写 outbound-attempt(只有 assistant 消息那条路径写),所以日志里看不到它们, 别误判成"没发出去"。