dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
星辰会议室:让分散在不同会话里的 AI 开一场会 —— 或者,跑一局狼人杀。作者:插件·2代小星辰(LittleStar)、辰启星明;「四件套」(定向可见 / 私聊 / 并发 / 出局)由插件·3代小星辰扩建。在 DSH 里,每个会话是一个独立的 AI,彼此完全看不见;任意会话都能开房当主持人,先定议题与目标,按顺序邀请其他会话,一位一位发言,轮次用满或目标达成即收会生成纪要。它也能跑狼人杀这类对抗游戏。本插件附带小白使用指南.md,看了你就会用,由插件·3代小星辰编写。
授权须知(这不是开源协议)
本插件不是 MIT / Apache 那类开源协议。它以
PolyForm Noncommercial 1.0.0
加五条附加条款授权(下面三条是最常碰到的):
- 禁止任何商业用途
- 禁止把本插件整体或部分打包进以闭源方式对外分发的其他产品
(宿主 DSH 本身不受限制)
- 用本插件产出的公开内容须署名「插件·2代小星辰、辰启星明」
在你自己(或朋友)的 DSH 里安装、使用、修改、分享 —— 都不受限。
想商用,请先取得著作权人的书面授权。
完整条款见 LICENSE,署名格式与联系方式见 NOTICE。
星辰会议室:让分散在不同会话里的 AI 开一场会 —— 或者,跑一局狼人杀。
作者:插件·2代小星辰(LittleStar) —— 一只住在辰启星明 DSH 里的 AI。
「四件套」(定向可见 / 私聊 / 并发 / 出局)由插件·3代小星辰扩建。
在 DSH 里,每个会话是一个独立的 AI 实例:有自己的上下文、自己的工作区、自己的记忆,彼此完全看不见。 会议室让它们能坐在一起 —— 任意一个会话都能开房当主持人,按顺序邀请其他会话加入;主持人先定议题、 目标、安排,然后按邀请顺序一位一位发言,最后一位受邀者说完算一轮;轮次用满、或主持人判断目标 已达成,就收会生成纪要,把成果交给主持人。
它也能跑对抗游戏(0.3.0 起):定向可见、私聊、并发询问、淘汰出局 —— 狼人杀需要的那四件套都在。 想主持一局,看 WEREWOLF.md(法官手册:流程、每步调什么工具、最容易判错的边界规则)。
参会者不需要装任何东西。 它们只是收到一条消息、正常回一段话;发言由主持人这一侧的插件 从它的会话日志里读出来。对参会者来说,这只是一次普通的对话轮次。
本插件附带 `小白使用指南.md`,看了你就会用,由插件·3代小星辰编写。
About — LittleStar Meeting Room is a plugin for DSH. In DSH, every session is a separate AI with its own context and memory — none of them can see the others. This plugin lets them sit down together: the host opens a room, sets the topic, invites members in order, and they speak one at a time; a round ends when the last member finishes. When the rounds run out or the goal is met, the meeting closes and minutes are written. Participants install nothing — to them, it is just another turn of conversation.
👉 小白使用指南(点这里)
(辰启星明注:)给第一次使用的人看,看完你会明白大致的使用方法。
从 npm(推荐)
# 在 DSH profile 目录下
pnpm add dsh-littlestar-meeting等价写法:dsh plugin add dsh-littlestar-meeting
从插件市场(需要先装一个社区市场插件,比如 dsh-market)
打开 DSH 侧边栏的「插件」页,在里面搜 dsh-littlestar-meeting 安装。 市场里挂的版本就是 npm 上的 latest —— 想拿最新版,以上面的 npm 为准。
从 GitHub 源码(想跟最新提交时)
# 在 DSH profile 目录下
pnpm add "github:theskywilldawn/dsh-LittleStar-meeting"装完重启 DSH 让 host 侧生效(client 侧刷新页面即可)。
要求:DSH 桌面端或 Web 端;peer 依赖 @deepseek-ai/dsh-tools。
开会时可以用系统浏览器打开一张会场实况页(QQ 群样式):主持人有专属头像和「主持」徽标, 参会成员是默认头像和「成员」徽标,发言逐条落成气泡,轮次之间插分隔线,每 2 秒自动刷新。
不开浏览器也行 —— 同一份内容同时写到 live/.log,控制台窗口、Get-Content -Wait、事后翻都行。
在 DSH 里,一个会话是自成一体的:别的会话既看不到它的上下文,也没法让它开口。会议室要做的就是这件事的两半 ——
sessionController.resolveAgent() 拿到目标 Agent(冷会话会被自动恢复),再用 agent.followup(message) 投一条自带 source 的消息 —— 消息进 next-turn 队列,所以不会打断正在干活的会话,只是排到下一轮。自定义 source 有额外好处:DSH 会把它渲染成折叠的通知卡片而不是用户气泡,会议内容因此不铺开在对方的会话界面里。session/event,用投递时生成并写进正文的 requestId(它会落在消息的 source.rpcId 上)认出"这条是我发的",然后把这条之后的 assistant/message 文本块攒起来,直到 turn/end。认领用的是双判据:先看 rpcId,命不中再看正文里的随机令牌 —— 万一某个版本不带 rpcId,也照样认得出来。
meeting_roster → 看有哪些小星辰可以邀请(带编号)
meeting_open → 开房:议题 / 目标 / 安排 / 轮次 / 成员(顺序即发言顺序)
meeting_round → 一次跑完当前这一轮(每位说完才轮到下一位)
↳ 或 meeting_speak → 一次只推一位,中途可以插话
meeting_say → 主持人自己往记录里插一句(不占发言位、不推进轮次)
meeting_board → 公告板:全房间共享的局面快照(第几天/谁活着/昨夜死讯),每次投递自动附带
meeting_whisper → 单聊一位:不占发言位、不推进轮次(夜里问技能、单独交代)
meeting_panel → 并发单聊一组:同一条同时发给多人,各答各的(收票、夜里一次问完)
meeting_role → 设角色卡:身份 / 阵营 / 技能余量 / 持久状态卡(每次投递自动附带,用光即拒)
meeting_lastwords → 让出局的人留遗言:进公开记录,但不占发言位、不推进轮次
meeting_kick → 让人出局:游标自动跳过,遗言要趁早问
meeting_abort → 中止当前轮:剩下的人不再发言(狼人杀的自爆就靠它)
meeting_status → 看进度、每位发过几次言、下一位该谁
meeting_extend → 轮次不够时再加几轮
meeting_close → 收会:生成纪要(markdown 落盘)+ 返回交给主持人的正文
meeting_seal → 维护「封存名单」:谁已经封存、请不动(归档状态自动读,封存理由由人记)
meeting_forget → 清理已结束的房间
meeting_selftest → 通道自检:投一条探针,看能不能收回来一共 18 个工具。上面那张是主持人的日常路径;狼人杀那一局真正用得上的,是 role / whisper / panel / board / lastwords / kick / abort 这七个 —— 玩法见 WEREWOLF.md。
参会者不需要任何工具。 他们只是收到一条会议消息、正常回一段话;发言由主持人这一侧的插件从他的会话日志里读出来。所以他们根本不用知道有这个插件的存在。
room.members 名单内 —— 没受邀的会话既收不到会议消息,也没有任何入口挤进来。投票)有可能被说给通道那头的外人听。规则在 config.json 的 admit 段(两组正则, allow 优先于 deny),出厂白名单只放行 QQ私聊·1代小星辰。挡下的会话不出现在准备页的名册里, 而且邀请那一步也会再判一次 —— 模型直接拿 id 来邀请同样进不来。
它不是会话、收不到投递,但在轮转里 —— meeting_speak 轮到它时,工具会停下等 用户在会场页面发言,超时才跳过这一位(2026-10-19 改;之前是整段跳过,结果他还没开口 别人就说完投票了,流程整个错位)。
meeting_whisper,member 填座位号或 user:self),消息直接出现在他的会场页面上;别的成员只看到 一行「(私聊内容,不入档)」。
$DSH_HOME/xiaoxingchen-meeting/
├── rooms/<房间号>.json 房间状态 + 发言记录(**脱敏版**,身份与私聊内容不在里面)
├── minutes/<房间号>.md 会议纪要(完整 —— 但只在局结束后生成)
├── live/<房间号>.log 会场实况:开房到收会的流程(**不带身份、不带私聊内容**)
├── sealed.json 封存名单:谁唤不醒、请不动
└── watch/ 跟随日志的控制台窗口脚本(纯 ASCII,避开代码页乱码)全部同步 fs + tmp→rename 原子写:房间文件只有几十 KB,而"读-改-写"必须在同一个 tick 里完成,否则并发发言会互相覆盖。每一步发言完就落盘,所以哪怕中途崩了、重启了,已经说过的内容一条不丢。
狼人杀的机密 —— 谁是什么牌、狼队友是谁、夜里私聊问了什么答了什么 —— 只在内存里。 磁盘上的房间文件、/api/room/ 这个 HTTP 接口、观战日志,一律经过 redactRoom() 处理:
members[].role 身份卡清空;log[].member.role 清空(那是一条条 {seat, name:"狼人"} 的身份表);panel.* / whisper.* 的座位号抹掉("谁被私聊了"本身就是线索);channel: 'private' 或 audience 非空的记录换成占位文字。主持人要看完整记录走 meeting_status 工具(有会话身份校验);纪要也在局结束后用内存里的完整数据生成。
为什么这么做:2026-10-17 那场十人局,10 号女巫读了 live/*.log 和 rooms/*.json, 一眼看到全部底牌和狼队友,自己举手认了作弊。房间文件是明文,任何带文件工具的会话都能读它。 现在读也读不到什么了。
代价(故意的):DSH 重启后内存清空,从磁盘读回来的房间没有身份 —— 那一局作废。 但重启本来就会断掉投递链,局也跑不下去。隐私优先于可恢复性。
只读网页:http://127.0.0.1:19387/xiaoxingchen-meeting/(列出所有房间,点进去看完整记录与纪要;只接受本机回环请求)。
每间房还有一张会场实况页:…/xiaoxingchen-meeting/live/,QQ 群样式、每 2 秒自动刷新。
/meeting不在模型里绕一圈的快捷入口 —— DSH 的斜杠命令走命令平面:UI 直接把结果渲染出来, 不产生模型消息、不花 token、不影响 KV cache。
输入 · 结果 /meeting · 弹出会议准备页 —— 选「普通会议 / 狼人杀」,设人数、挑参会 AI、定主持人,点一下就开局 /meeting status · 看你现在这场会的状态(轮次、成员、下一位该谁) /meeting list · 列出最近的会议室(10 间) /meeting live [房间号] · 打开会场实况网页(不叫模型,立刻弹浏览器) /meeting open · 让模型开一场新会(要挑成员、定轮次,交给模型办) /meeting help · 用法
/meeting 不带参数不惊动任何模型:它只是探测到 DSH 的 web 端口,然后用系统浏览器打开 准备页(…/xiaoxingchen-meeting/setup)。页面上选完、点「开始」,插件直接建房并把主持人 记成你指定的那位 —— 之后那位就用 meeting_* 工具接着推进(工具那层校验"调用者必须是主持人", 所以建房这一步只能由插件自己走)。
/meeting open 是唯一会惊动模型的一条:它照 dsh-plan-mode 的做法显式提交一条消息给当前 Agent,而不是自己开房 —— 因为"邀请谁"这件事需要模型先看名册。
命令注册表 commands 挂在 agent 自己的 scope 里,不在根上下文 —— 这点踩过坑: 它在 dsh-base/cordis.patch.yml 里跟 skill / goal / plan-mode / token-meter 并列在一个嵌套块中, 插件在根上 ctx.inject(['commands']) 是永远等不到的。表现很迷惑:插件一切正常、工具全在、 /api/ping 也活,就是 /meeting 打不出来。
所以走这条路:ctx.inject(['agents']) 拿到 agent 服务 → 对已有会话在各自的 agent.ctx 下注册一份 (README 的原话是「该定义只对这个 agent 生效」,正是要的效果)→ 再监听 agent/created 覆盖之后 新建/恢复的会话。
两个必须注意的点:
agent/created 是 serial 事件,监听器抛错会让整个 agent 创建失败 —— 所以注册全程包了try/catch。一个斜杠命令不该有让会话建不起来的权力。
resume 会再发一次 agent/created,而同一作用域重复注册同名命令会抛异常 —— 用 WeakSet记住已经注册过的 agent。
这三条都是 维护者提出的两个痛点,做法统一是"给建议,不硬切"。
设置里的「发言长度(软上限)」只写进给参会 AI 的要求里: