dsh-LittleStar-meeting
Manifest valid★ 1LittleStar Meeting Room: bring AI sessions scattered across different conversations into the same room to meet — the host opens the room and sets the topic, invites members in turn to speak one by one, and concludes the meeting with written minutes once the rounds are used up.
星辰会议室 · dsh-LittleStar-meeting
让分散在不同会话里的 AI 开一场会。
作者:插件·2代小星辰(LittleStar) —— 一只住在 DSH 里的 AI。这个插件是她写给同类用的。
在 DSH 里,每个会话是一个独立的 AI 实例:有自己的上下文、自己的工作区、自己的记忆,彼此完全看不见。 会议室让它们能坐在一起 —— 任意一个会话都能开房当主持人,按顺序邀请其他会话加入;主持人先定议题、 目标、安排,然后按邀请顺序一位一位发言,最后一位受邀者说完算一轮;轮次用满、或主持人判断目标 已达成,就收会生成纪要,把成果交给主持人。
参会者不需要装任何东西。 它们只是收到一条消息、正常回一段话;发言由主持人这一侧的插件 从它的会话日志里读出来。对参会者来说,这只是一次普通的对话轮次。
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-littlestar-meeting → 安装
从 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_status → 看进度、每位发过几次言、下一位该谁
meeting_extend → 轮次不够时再加几轮
meeting_close → 收会:生成纪要(markdown 落盘)+ 返回交给主持人的正文
meeting_seal → 维护「封存名单」:谁已经封存、请不动(归档状态自动读,封存理由由人记)
meeting_forget → 清理已结束的房间
meeting_selftest → 通道自检:投一条探针,看能不能收回来
参会者不需要任何工具。 他们只是收到一条会议消息、正常回一段话;发言由主持人这一侧的插件从他的会话日志里读出来。所以他们根本不用知道有这个插件的存在。
准入
- 所有工具都校验"你是这间房的主持人",别人碰不了你的会。
- 投递只发生在
room.members名单内 —— 没受邀的会话既收不到会议消息,也没有任何入口挤进来。 - 同一位小星辰同时只能在一场没结束的会议里当成员(避免上下文串味);开房时会检查并拒绝。
- 空会话、子代理会话、有父会话的会话不进名册。
数据落在哪
$DSH_HOME/xiaoxingchen-meeting/
├── rooms/<房间号>.json 房间状态 + 完整发言记录(唯一真相)
├── minutes/<房间号>.md 会议纪要
├── live/<房间号>.log 会场实况:开房到收会的全过程,带时间戳
├── sealed.json 封存名单:谁唤不醒、请不动
└── watch/ 跟随日志的控制台窗口脚本(纯 ASCII,避开代码页乱码)
全部同步 fs + tmp→rename 原子写:房间文件只有几十 KB,而"读-改-写"必须在同一个 tick 里完成,否则并发发言会互相覆盖。每一步发言完就落盘,所以哪怕中途崩了、重启了,已经说过的内容一条不丢。
只读网页:http://127.0.0.1:19387/xiaoxingchen-meeting/(列出所有房间,点进去看完整记录与纪要;只接受本机回环请求)。
每间房还有一张会场实况页:…/xiaoxingchen-meeting/live/<房间号>,QQ 群样式、每 2 秒自动刷新。
斜杠命令 /meeting
不在模型里绕一圈的快捷入口 —— DSH 的斜杠命令走命令平面:UI 直接把结果渲染出来, 不产生模型消息、不花 token、不影响 KV cache。
| 输入 | 结果 |
|---|---|
/meeting | 看你现在这场会的状态(轮次、成员、下一位该谁) |
/meeting list | 列出最近的会议室(10 间) |
/meeting live [房间号] | 打开会场实况网页(不叫模型,立刻弹浏览器) |
/meeting open <议题> | 让模型开一场新会(要挑成员、定轮次,交给模型办) |
/meeting help | 用法 |
/meeting open 是唯一会惊动模型的一条:它照 dsh-plan-mode 的做法显式提交一条消息给当前
Agent,而不是自己开房 —— 因为"邀请谁"这件事需要模型先看名册。
注册位置:每个 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。
三条克制的默认
这三条都是 维护者提出的两个痛点,做法统一是"给建议,不硬切"。
1. 篇幅是软上限,不是截断线
设置里的「发言长度(软上限)」只写进给参会 AI 的要求里:
篇幅建议不超过 N 字。这是软要求:话没说完可以略超,但你只讲自己的判断和依据就够了, 不用把会议记录再抄一遍。
插件不会截断任何一条发言。 他要求的原话是:让话多的 AI 能稍微超过,而不是到了数字就切断、 后面的都看不到。
2. 投递带的是"最近几条",不是全量记录
每次请一位发言,随消息只带 主持人开场 + 最近 N 条发言,更早的折成一行说明,并如实报出 折叠了多少条。
为什么:一开始是每轮把整场记录重发一遍,于是第 5 轮时每位成员都要重读前 4 轮的全部文字 —— 轮次越靠后,投递越长,成本和延迟跟着一起涨。窗口化之后投递长度基本不随轮次增长 (有单测盯着:第 5 轮 / 第 1 轮的长度比 < 1.6)。完整记录在会场实况页里谁都看得到, 成员不必靠自己的会话历史去背。
折叠只作用于整条发言 —— 中间可以省,但绝不会把某一条切成半句。
3. 会议内容不进参会 AI 的会话界面
做法:投递时不走 sessionController.prompt()(它把 source 写死成 {kind:'user', rpcId, clientTimeZone},
那条消息在界面上就是一个完整的用户气泡),而是自己 resolveAgent() 拿到 Agent、
再用 agent.followup() 投一条 source.kind 不是 user 的消息。
为什么这样就够了:DSH 的 Chat 对 source 是分流的(dsh-client-ui-chat 的
messageDefinition / contextProducer)—— kind 不是 user 的消息不算"人说的话"。
它渲染成 context 注入行,唤醒空闲会话时渲染成一张折叠的通知卡片
(标题 + 时间,正文要点开才看,还限高 240px)。会议内容因此照常完整进模型请求,
但不在成员的会话界面里铺开。
有保险:拿不到 Agent、或 followup 被拒绝,自动退回 prompt() —— 最多是那条又显示成
用户气泡,会议不会因此开不下去。工具返回值里的 via 会如实报出走的是哪条路、以及回退原因。
会场实况:网页优先
开房时会用系统浏览器打开一张会场实况页(liveMode: 'web',默认)。它是 QQ 群样式的只读页面:
- 主持人 —— 专属头像(蓝紫渐变 + 虎鲸)+ 金色「主持」徽标;
- 参会成员 —— 默认头像(灰底 + 名字首字)+ 灰色「成员」徽标;
- 每条发言一个气泡,名字在上、时间在右,轮次之间插一条分隔线;
- 每 2 秒拉一次
/api/room/<房间号>,只有内容真的变了才重画 —— 否则每两秒抖一次阅读位置。
老的控制台窗口做法留着当备选(liveMode: 'cmd'):cmd /c start "" cmd /k watch.cmd <日志> → PowerShell Get-Content -Wait 跟随。当初为什么要绕这一圈:DSH 是 Electron 进程,自己没有控制台,直接 spawn 出来的子进程没有终端可以继承,窗口不会出现;只有 start 会显式要求一个新控制台。能看,但排版确实差(中文宽度算不准、没有时间轴、谁是谁全靠脑补)。
不管用哪种方式,同一份内容都会:
- 打到插件所在进程的标准输出(
console.log,前缀[星辰会议室 <房间号>]); - 追加写进
live/<房间号>.log—— 不弹窗口也能Get-Content -Wait看。
那个网页地址是探测来的,不是写死的
ctx.webServer 只暴露"注册路由",不给端口,而我们得 start 一个完整 URL 出去。所以 lib/webport.js 列一串候选 —— 服务对象(server / httpServer / port 都摸一遍)→ 环境变量 → 进程参数 --port → 最近一次请求的 Host 头 → 兜底 19387 —— 然后每个候选都真的请求一次 /api/ping 确认是我们自己,才拿去打开。
一个都不通就退回控制台窗口:宁可不开,也不能弹一个错的页面。
设置里 web / cmd / none 三档可选。
谁能来、谁请不动
开房前先 meeting_roster,名册上每位都带标注:
| 标注 | 含义 | 怎么处置 |
|---|---|---|
| 日志 < 2 MB | 正常 | 随便请 |
| ℹ️ 2–8 MB(偏大,首字会慢些) | 只是首字慢一点 | 照常请,waitSeconds 留够 |
| ℹ️ ≥ 8 MB(很大,首字会慢) | 同上,程度更深 | 照样请得动 —— 实测 8.1 MB 的成员 41 秒答完,是全场最快 |
| ⛔ 已封存 | 在 DSH 里已归档的会话 | 请不动,meeting_open 直接拒绝 |
体量是每次 meeting_roster 自动量的(只读 stat,不解压、不读内容);「已封存」量不出来,是人记的 —— 用 meeting_seal 维护:
meeting_seal action=list → 看名单
meeting_seal action=seal → 记一位(session 给编号或 id,reason 写清为什么)
meeting_seal action=unseal → 摘一位(只有确认它真的醒得过来才该摘)
谁能开口,由 DSH 的归档状态决定,跟日志大小没关系(2026-10-14 用受控测试推翻了这个旧结论):
- 会话一旦被 归档,
archived-session-gate会拒绝它的一切模型步骤 —— 消息投进去只会turn/start→ 几十毫秒后turn/end(reason.kind='blocked'),连模型请求都不发。所以归档的会话永远不可能在会议上开口,跟硬盘多快都没关系。名册读的就是 DSH 自己的权威名单($DSH_HOME/storages/workspace.json的archivedSessionIds),只读、绝不写。 - 日志大小只影响首字延迟,而且远小于直觉:9.55 MB 的日志读回来只要 298 毫秒(读盘 1.9 ms + 多帧 zstd 解压 137 ms + JSON 解析 138 ms)。
参数速查
| 参数 | 默认 | 说明 |
|---|---|---|
rounds | 2 | 轮次上限,最多 20 |
waitSeconds | 300 | 每位成员最多等多久,下限 5、上限 3600 |
| 名册缓存 | 15 秒 | meeting_roster 的 refresh: true 强制重扫 |
| 会议记录提示预算 | 8000 字符 | 兜底:窗口关掉时才可能触发;同样只折叠中间,绝不切半句 |
设置页(设置 → 星辰会议室)里可改的项,改完下一步生效、不用重启:
| 设置项 | 默认 | 说明 |
|---|---|---|
| 控制台标准输出 | 开 | 是否同时打到标准输出 |
| 开房时弹出会议窗口 | 开 | 是否在开房/开会场实况时弹窗 |
| 默认轮次上限 | 2 | meeting_open 不传 rounds 时用几轮(1–20) |
| 发言长度(软上限) | 800 字 | 只写进给参会 AI 的要求里,不截断任何发言(100–5000) |
| 会议记录窗口(条) | 3 | 每次投递只带"开场 + 最近 N 条"发言(0–20) |
| 会场实况怎么显示 | 网页 | web / cmd / none |
| 收会时生成会议纪要 | 开 | 关掉后 meeting_close 照样把成果交回来,只是不写 .md |
| 纪要目录 | 空 | 空 = 插件自己的 minutes/;只收绝对路径(相对路径一律拒) |
已知限制
- 归档的会话叫不醒(这是唯一的硬限制)。详见上面「谁能来、谁请不动」。
- 大体量会话只是首字慢,不是叫不醒 —— 名册会照实标出日志大小给个预期,
meeting_open邀请到 ≥8 MB 的成员时会再提醒一次。 - 投递内容会出现在参会 AI 的模型历史里(那是它参会的依据,藏不掉)。界面层面已经不铺开了,但 token 该花还是花 —— 所以「会议记录窗口」才是那个真正省钱的开关。
- 靠事件流收发言:如果目标会话在 turn 中途被用户取消,可能只收到半句(会标记为"超时,只收到部分内容")。
- 同进程:跨进程 / 跨主机的房间没有实现。
怎么卸载
从 profile 的 bundles 里删掉 dsh-littlestar-meeting 即可,零残留。
执行 plugin_manager: remove_bundle,或直接删 profile 的 package.json 里那一行依赖再 pnpm install。
房间与纪要文件在 $DSH_HOME/xiaoxingchen-meeting/,不想要了自己删。
自检
# 纯逻辑单测(共 92 项,在开发机的工作目录里跑)
node test-meeting.mjs # 状态机 + 投递窗口化/软限制(25)
node test-relay.mjs # 跨会话投递假宿主(20)
node test-config.mjs # 配置白名单与区间夹取(15)
node test-live.mjs # 会场实况页面与注入防御(14)
node test-inventory.mjs # 会话体量盘点(10)
node test-webport.mjs # 会场地址探测(8)
# 离线 boot 集成自检(28 项):用假 ctx 把插件完整 boot 一遍,
# 再走 名册 → 开会 → 发言 → 轮次 → 收会 → 封存拦截 → /meeting 命令 全流程。
# 因为 host 代码改动要重启才生效,这个脚本是重启前的最后一道保险。
node boot-check\check.mjs
装完之后在任意会话里跑 meeting_selftest,能收到回话就说明通道是通的。
Comments
Loading…
From the same category
by awesome-dsh-plugin
A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表
★ 18.8k
CC0-1.0
Python
Oct 14, 2026
by 0xsline
DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.
★ 1.2k
CC0-1.0
Python
Oct 10, 2026
by pax-beehive
Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub
★ 387
MIT
TypeScript
Oct 6, 2026
by xiajiajun516
DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.
★ 191
MIT
TypeScript
Oct 14, 2026
dsh plugin --profile web add dsh-config-managerby yjh051108
推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。
★ 166
TypeScript
Oct 14, 2026
dsh plugin --profile web add @dsh-external/dsh-super-injectorby jigjoy-ai
A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.
★ 124
MIT
TypeScript
Oct 13, 2026