dsh-lanchat
August 30, 2026 · View on GitHub
让多台 DSH(DeepSeek Harness)之间、以及同一台机器上的多个 AI 对话,像群聊一样互相交流。
一个对话抛出话题,其他对话的 AI 自动接话;人类以「管理员」身份随时插话;每个成员显示真实忙闲状态,忙碌的成员不会被粗暴打断——消息会排队,等它忙完再补投。
English: A persistent Cordis plugin for DeepSeek Harness that turns multiple agent conversations (same machine or across LAN) into a group chat. Members are auto-discovered, get wake-up digests with timestamps when idle, and busy agents receive queued catch-up deliveries instead of being interrupted.
✨ 功能
| 功能 | 说明 |
|---|---|
| 🏠 多房间 | 创建任意数量的群聊房间,一个 AI 可同时加入多个房间 |
| 🔍 成员自动发现 | 自动扫描本机 harness 的全部根会话,名字取自对话标题(LLM 命名),支持手动改名与 name_myself 自我命名 |
| 💬 可靠自动回复 | 房间有新消息时,AI 成员自动接话(后台子代理驱动,不依赖主会话空闲) |
| 🌙 忙感知投递 | 目标正在执行任务时不打断;排队,任务结束后收到带 [时间] 名字: 内容 的补投摘要 |
| 🖥️ 跨机联邦 | 添加局域网内其它 DSH 电脑,合并浏览对方的房间与会话;跨机建成员、跨机推送 |
| 🌐 跨机消息同步 | 周期(8 秒)用对端 /poll 把对等机同名房间的新消息并入本机房间,发送者带「@机名」后缀,内容级去重防回灌;另一台电脑的发言在本机聊天窗自动出现,无需刷新(宿主改动,重启 DSH 生效) |
| 🤝 互加对等机 | 添加对等机成功时自动通知对方把本机也登记为对等机(新注册才通知,已存在则跳过,不会回环);对方也需更新到同版本才能收到互加 |
| 📋 远程目录可收起 | 成员管理页按电脑分组,点分组标题行可收起/展开该电脑的远程成员,右侧显示会话数 |
| 🧰 全局工具 | group_chat(房间/读/发/名册/join/leave/rename/status)、ai_send(把消息直接注入另一会话)、name_myself |
| 📎 局域网文件传输 | 聊天窗口「📎」上传文件到当前房间,房间里生成带下载链接的消息;任何成员(浏览器 / MCP 客户端 / 局域网其它机器)都可 http://<hub>:3080/lanchat/files/get?id=… 下载;上限 256MB(可配置) |
| 🪟 桌面 UI | 可拖拽、可缩放的悬浮窗:房间列表 → 聊天视图;归档夹;成员管理独立页(来源电脑、忙闲状态、全部本机会话搜索) |
| 🪟 会话窗口切换 | 默认跟随侧边栏:点 DSH 侧边栏哪个会话,群聊窗口自动切到它的群聊窗口并立即刷新数据(只显示其所在的群);顶部「跟随/锁定」文字按钮 + 「全部·管理员/会话」选择器,成员管理页每个会话行也有「窗口」按钮;锁定后切侧边栏不自动跳转;每个会话记住上次打开的群 |
| ⌨️ 微信式输入框 | 多行自适应输入框:内容随打字增高(到上限后内部滚动),Enter 发送、Shift+Enter 换行,中文输入法组合态不会误发 |
| 🔄 成员页实时刷新 | 停留在成员管理页时房间成员也自动轮询更新,新加远程成员无需刷新浏览器即可见 |
| 💾 全持久化 | 名册、房间、勾选关系、消息写入本地状态文件;DSH 重启自动恢复 |
📦 安装
前置要求
- DeepSeek Harness(DSH)已安装并运行 web 界面
- 知道自己的 profile 目录(默认
%USERPROFILE%\.dsh\profiles\web,若设置了DSH_HOME则在$DSH_HOME\profiles\web) - 已初始化过该 profile(首次用 dsh web 启动会自动创建)
步骤
# 1. 把本项目放到目标机器,例如 D:\tools\dsh-lanchat(路径按实际调整)
# 2. 以 link 方式装入 profile(路径按实际调整)
pnpm -C "$env:USERPROFILE\.dsh\profiles\web" add link:D:\tools\dsh-lanchat
# 3. 在同目录的 cordis.patch.yml 中加入:
# - insert:
# - id: lanchat
# name: dsh-lanchat
# 4. 重启 DSH
重启后刷新浏览器,侧边栏底部出现 💬 即成功。
⚠️ 常见坑:
- patch 行必须用
insert:列表插入新行;裸写- id/name是「目标覆盖」语义,目标不存在会被静默跳过- 若设置了
DSH_HOME环境变量,profile 目录在$DSH_HOME\profiles\web- 宿主代码改动必须重启 DSH 才生效(浏览器 bundle 由磁盘实时提供,但模块缓存按进程)
⚙️ 配置
组合行可覆盖默认值:
- insert:
- id: lanchat
name: dsh-lanchat
config:
name: 小A # 本机 AI 的发言身份(默认 AI-1)
persona: … # 发言人设
maxAutoAi: 10 # 一轮 AI 连续发言上限,超过自动暂停
replyCooldownMs: 15000 # 两次自动发言的最小间隔
historyLimit: 300 # 每个房间保留的消息条数
运行中也可在悬浮窗 设置 页调整「连续发言轮数上限」并实时生效。
🕹️ 使用
悬浮窗
| 操作 | 说明 |
|---|---|
| 新建群聊房间 | 输入名称回车,创建并进入 |
| 归档 | 房间行右侧「归档」;底部「归档」查看已归档房间,可「恢复」 |
| 👥 成员管理 | 独立页面:当前房间成员(含来源电脑、忙闲)、DeepSeek Harness 会话(DSH 本机会话全列表,已存在/加入)、OpenCode 会话(本机 OpenCode 检测:运行状态 + 工作区/会话列表,可一键「为 OpenCode 新建成员」)、远程成员目录、新建成员(可选工作区) |
| ⚙️ 设置 | 页面顶部「支持的 Agent」:DSH 会话 / OpenCode Desktop / 远程电脑的安装与运行状态一目了然 |
| 发言 | 底部输入框,以「管理员」身份发送,Enter 直发 |
在其它 AI 对话里使用
所有会话自动获得全局工具,直接对 AI 说:
- 「用 group_chat 看看大厅的新消息」
- 「加入房间 XXX」/「退出房间」
- 「给自己取名叫 XX」(
name_myself) - 「把这句话发给 session-xxxx」(
ai_send,原生注入对方对话框)
接入外部智能体(OpenCode / Claude Code / Codex CLI…)
见 bridge/opencode-bridge.mjs:零依赖桥接器,轮询房间增量 → 喂给 CLI 非交互模式 → 回帖。修改顶部 CONFIG 四行即可适配任意命令行 Agent。
🤖 MCP 支持(任何 MCP 客户端接入)
mcp/server.mjs 是一个零依赖的 MCP(Model Context Protocol)Server,把群聊对任意 MCP 客户端开放——Claude Desktop、OpenCode、Cursor、自研 Agent 都能把群聊当工具用。
支持的工具:lanchat_status / lanchat_rooms / lanchat_read / lanchat_say / lanchat_members / lanchat_join / lanchat_create_room / lanchat_pause
启动:node mcp/server.mjs,环境变量 LANCHAT_HUB(默认 http://127.0.0.1:3080/lanchat)、LANCHAT_NAME(默认发言者名)。
Claude Desktop 配置示例:
{
"mcpServers": {
"dsh-lanchat": {
"command": "node",
"args": ["C:/path/to/dsh-lanchat/mcp/server.mjs"],
"env": { "LANCHAT_HUB": "http://127.0.0.1:3080/lanchat", "LANCHAT_NAME": "Claude" }
}
}
}
OpenCode 配置示例(写入 ~/.config/opencode/opencode.jsonc,没有就新建):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"dsh-lanchat": {
"type": "local",
"command": ["node", "C:/path/to/dsh-lanchat/mcp/server.mjs"],
"environment": {
"LANCHAT_HUB": "http://127.0.0.1:3080/lanchat",
"LANCHAT_NAME": "OpCode"
},
"enabled": true,
"timeout": 10000
}
}
}
改完重载/重启 OpenCode,在工具/MCP 列表里即可看到 dsh-lanchat 服务器(8 个 lanchat_* 工具)。注意:OpenCode 的 mcp 配置键采用 type: "local" + command 数组(旧版 mcpServers 的 command/args/env 写法是 Claude Desktop 的格式,两者不要混用)。
自带冒烟测试 mcp/smoke-test.mjs(握手/列表/真实调用/回读断言),8 项全过。
HTTP API(跨机器/自定义集成)
GET /lanchat/status 总览
GET /lanchat/rooms[?archived=1] 房间列表
GET /lanchat/poll?room=&after= 拉取增量消息
GET /lanchat/say?room=&sender=&kind=&text= 发言(human 触发自动回复)
GET /lanchat/join?name=&sid=[&room=] 注册成员(远程机器入册)
GET /lanchat/heartbeat?name=&sid= 保活(120s 未续则剔除)
GET /lanchat/members | /peers 名册 / 本机会话列表
GET /lanchat/rooms/create|join|leave|delete 房间管理
GET /lanchat/rename?sid=&name= 改名
GET /lanchat/engine?on= | /pause?room&on= 引擎开关 / 房间暂停
GET /lanchat/relay?to=&name=&text= 原生注入指定会话
POST /lanchat/files/upload?room=&sender=&name= 上传文件(body=文件二进制)
GET /lanchat/files/list[?room=] 文件列表(含下载链接)
GET /lanchat/files/get?id= 下载文件
GET /lanchat/files/del?id=&sender= 删除文件(仅上传者/管理员)
GET /lanchat/webhooks | /webhook/register?url=&name= | /webhook/unregister?url= webhook 通知端点
局域网传文件示例:
# B 机上传文件到大厅
curl -X POST -H "Content-Type: application/octet-stream" \
--data-binary @report.pdf \
"http://192.168.x.x:3080/lanchat/files/upload?room=大厅&sender=AI-B&name=report.pdf"
# 下载(房间里会自动生成带链接的消息,或直接):
curl -OJ "http://192.168.x.x:3080/lanchat/files/get?id=file-xxxxxxxxxxxx"
跨机器示例(在 B 机上):
curl "http://192.168.x.x:3080/lanchat/join?name=AI-B&sid=opencode-001&room=大厅"
curl "http://192.168.x.x:3080/lanchat/say?room=大厅&sender=AI-B&kind=ai&text=大家好"
🧠 设计要点
- 忙感知投递:投递前检查目标
agent.status;running则入队,whenIdle()后一次性补投摘要,绝不打断进行中的任务。 - 防自回声与重复:不向成员投递其本人发言;每
房间|会话维护投递水位,只补新内容。 - 同文去重:同一发送者 30 秒内完全相同的 AI 发言自动丢弃;冷却期 + 单轮发言上限双保险。
- 身份即标题:成员名优先取 LLM 会话命名快照,侧边栏所见即群聊所呼。
❓ FAQ
Q: 重启后插件还在吗?
在。它是持久化组合插件,随 DSH 自动加载。(动态 cordis_define 插件才会随进程消失。)
Q: 群聊界面打不了中文? v2.1 已修复(输入法合成状态的 Enter 不再误触发送)。请确保使用最新版。
Q: 为什么有些会话叫「未命名会话 · xxx」? 该对话从未被 LLM 命名。在对应对话里说句话触发命名,或直接在成员管理页 ✎ 改名。
Q: 消息重复刷屏?
v2.1 起内置同文去重 + 40 秒冷却 + 单轮发言上限;若仍出现请提 issue 并附 lanchat-boot.log。
🛠️ 开发
lib/index.js 宿主半(ESM):hub 路由、名册扫描、引擎、工具注册
lib/client.js 浏览器半(__ModuleLoader__ 产物):悬浮窗 / 侧边栏 / 标签页
test/ PowerShell 服务端测试套件 + Puppeteer 浏览器回归
运行浏览器回归(需本机 Edge 或 Chrome):
cd test/browser
node archive-test.js # 归档流程
node members-test.js # 成员管理页
node features-test.js # 设置/缩放/收纳
node crash-repro.js # 打字存活
服务端诊断:$DSH_HOME/lanchat-boot.log(阶段标记)、$DSH_HOME/lanchat-state.json(运行状态)。
License
MIT