dsh-chat-local
面向 DeepSeek Harness 的本地多 Agent 群聊插件。
一位参与者就是一个真实 DSH Session。 插件不复制 Agent 或模型配置:模型、权限、工作目录和会话历史始终由 DSH 自己管理。
群组 稳定的协作团队,持有成员、职责与默认配置
└── 对话 独立的工作上下文:消息、台账、材料、执行记录互不污染
└── 执行回合 一次有边界的成员唤醒与回复
它解决什么问题
让多个 Agent 协作,通常要么把同一份配置复制多遍,要么让它们共用一个上下文互相干扰,而且事后无法说清「谁在什么时候为什么改了这条结论」。
这个插件换一个做法:群聊只是编排层,不接管执行。成员是真实的 DSH Session,所以你在群聊里做的权限和模型设置,离开群聊后依然生效;反过来,DSH 自身的沙箱和审批也始终有效。
环境要求
| 依赖 | 说明 |
|---|
| DeepSeek Harness | 0.1.5-rc.2(适配其槽位系统;其他版本需自行验证) |
dsh-bridge | 必需。负责本机 Session 唤醒与消息投递 |
| Node.js | 与所运行的 DSH 相同 |
不需要远程服务,不依赖 dsh-weave。
插件版本号以 package.json 的 version 为唯一来源,/api/dsh-chat-local/health 直接读取它,不另行维护副本。DSH 兼容范围声明在 dsh.engines.dsh,支持该字段的安装器(如 dshmarket)会据此提示版本不匹配;两者都有回归测试锁定,避免升级时漂移。
安装
# 从 GitHub 安装到 web profile
dsh plugin --profile web add github:ALPSIYH/dsh-chat-local
# 本地开发时用 link: 方式
dsh plugin --profile web add link:/path/to/dsh-chat-local
安装后重启 dsh web,在 DSH 侧栏底部点击「群聊」进入工作区。
插件通过 cordis.patch.yml 注册自身,不修改 DSH 源码。它占用 DSH 的原生槽位(shell.overlay 覆盖层),「返回 DSH」一步恢复原界面。
快速开始
- 建群组 — 输入群组名称,加入已有 Agent 或新建 Agent。纯保存不创建原生 Session,也不会唤醒任何模型。
- 开对话 — 写下议题即可开始。每个对话拥有独立的消息、台账和成员绑定;首条人类消息会生成可编辑的议题标题。
- 让成员干活 — 默认「自动协作」:一条普通消息会按成员顺序依次征询。也可以切换为仅
@定向,或在消息里点名 @别名 精确路由。
- 看台账 — 顶栏「台账」把任务、决定、证据和分歧从聊天里抽成可追踪条目,带负责人、验收标准和来源消息。
成员之间可以 @ 彼此,形成 A→B→A 的因果链;普通 assistant 回复由 Session 事件自动回收进群聊,不要求 Agent 额外调用发送工具。
主要能力
协作路由
- 普通人类消息默认按成员顺序依次征询,单轮内不会并发争抢同一上下文。
- Agent 回复中的精确
@别名 优先路由给被点名者;人类直接输入 @别名 同样识别。
- 每个 Agent 在一条链内默认最多发言 3 次,整条链最多 10 次自动回复,避免无限互聊。
- 新消息令旧轮次过期,迟到回复不会污染新上下文。运行中的回合可从顶栏立即停止。
(pass) 表示本轮无新增内容;未继续 @ 时不追加点名轮次。
- 投递状态分别展示排队、已发送、已送达、思考中、已回复、跳过、失败和过期。失败投递可只重试失败的参与者,沿用原消息与因果链。
- 人类消息可追加「纠正」:原文不被改写,纠正关联原消息,并只通知曾收到原消息的参与者。
协作闭环台账
chat_work 提供 record / amend / acknowledge / progress / submit / review / comment 七种语义操作,贯穿一条明确的责任链:
| 环节 | 含义 |
|---|
| 分派 ≠ 收悉 | 负责人只能由本人确认;无负责人的任务可由成员认领 |
| 交付 ≠ 验收 | 提交必须标明材料或结果版本,进入 in_review;指定了独立验收人才由其确认,否则等待用户。负责人不能自验收 |
| 建议 ≠ 授权 | Agent 登记的决定初始为 proposed,不能自行变成 decided;分歧和证据不能由 Agent 单方关闭 |
除登记外,每个操作都要带事项 id、当前 revision、唯一操作 id,以及 1–8 条本房间的真实来源消息。身份取自执行工具的 DSH Session,且只允许该房间的有效群聊回合写入。幂等键相同且内容相同返回原结果,同键不同内容拒绝。
变更范围或负责人会清除旧的收悉/交付/验收并重新开放;归档不表示验收。每房间最多 1000 项台账、每项最多 1000 条历史事件,容量不足时拒绝新增而非截断历史。
章程自更新
房间的目标与协作章程可由 Agent 提议、全员确认后自动生效,不需要用户手动抄录:
chat_memory — 读取现行章程、近期版本、提案、最近 24 条公开消息与台账。不读取任何成员的私聊上下文。
chat_charter_propose — 提交完整的新章程文本,须带现行 baseRevision、理由和 1–8 条讨论消息 ID。
chat_charter_review — 执行 Session 只能代表自己确认或提出异议。沉默、模型普通表态或聊天里的「同意」都不是工具确认。
全体现有成员确认后写入新版本并在时间线公告;出现异议则保留旧章程,在轮次预算内让提案人处理。审阅与返修共用原有的每人/总回复上限,不开启无限后台轮次。
权限模型
每个房间带递增的策略版本,每条消息记录其提交时的策略版本与动作模式:
| 模式 | 行为 |
|---|
discuss_only | 只读讨论/审计。群聊额外拦截命令、文件修改和未知副作用工具 |
read_only_audit | 只读审计,语义同上,用于明确的审计场景 |
inherit_dsh | 不修改原生配置,移除群聊额外拦截,由各会话当前的沙箱与审批控制 |
workspace_write | 把现有成员同步为 DSH 原生 workspace-write / ask |
full_access | 同步为 danger-full-access / never 并移除群聊额外拦截 |
后两项真的调用 DSH 原生权限预设设置成员的真实 Session,而不是只改台账或提示词——这些设置在离开群聊后仍然生效。需要用户明确勾选影响提示才会应用,应用后不会自动启动任务。
变更必须由用户在权限界面明确执行;Agent、章程提案和台账决定都不能改变房间策略。批量变更前会检查所有成员是否空闲。原生服务缺失或预设不匹配时给出具体错误,不虚报成功。
材料读取
chat_read_document 可在群聊回合内安全地分段抽取 DOCX 或文本,无需 shell:
- 读取范围限于参与者工作目录,或用户在群里明确共享的单个路径;不开放邻近文件或整个目录。
- 文本上限 1 MB,DOCX 压缩文件上限 20 MB。按受限 ZIP/XML 解析,不运行宏、不跟随外部链接、不修改原文件。
- 返回正文、表格、脚注、尾注、批注、页眉页脚的 XML 定位码与版本哈希。这是结构化文本抽取,不等于页面排版或图像审查。
历史记录只作为带 SHA-256 的只读来源引用:插件区分 Artifact(逻辑文件)、Version(内容哈希版本)和 Replica(某会话工作目录中的副本),不复制或改写原文。
界面
- 沿用 DSH 的主题颜色、字号与线性图标,不使用 Emoji。
- 桌面默认展开房间栏;680px 以下改为房间抽屉,1120px 以下详情使用遮罩抽屉。
- 消息按日期分组,「回应」可跳转并短暂高亮原消息。向上阅读历史时新消息不会抢走滚动位置,而是显示「新消息」按钮。
- 草稿按房间保存并在返回后恢复;异步发送结果会校验房间 ID,不会把 A 房消息写进正在查看的 B 房。
- Esc 只逐层关闭选择器、确认框、检查器或新建表单,不会退出群聊。
- 删除房间是可恢复的软删除:房间移入「已删除」,消息、成员关系和真实 DSH Session 全部保留。「移出」只移除房间成员关系,不删除 Session。
Agent 工具
| 工具 | 用途 |
|---|
chat_create | 创建群聊并让当前 Session 加入 |
chat_join | 让当前 Session 加入已有群聊 |
chat_invite | 把另一个存活的本地 Session 加入群聊 |
chat_send | 以当前 Session 身份发送消息 |
chat_rooms | 列出可见的群聊房间 |
chat_memory | 读取共享记忆(章程、提案、近期消息、台账) |
chat_work | 维护协作台账(record/amend/acknowledge/progress/submit/review/comment) |
chat_manage | 提出台账整理清单(归档/终止/取消过时依赖),由用户一次确认 |
chat_charter_propose | 提交章程修订提案 |
chat_charter_review | 独立审阅章程提案 |
chat_read_document | 在群聊回合内只读抽取 DOCX/文本 |
界面的 HTTP 接口挂在 /api/dsh-chat-local/*。
本地数据
房间状态保存在 ~/.dsh/dsh-chat-local/rooms.json,目录权限 0700、文件权限 0600,当前状态版本 v15。
- 读取到不支持的未来版本或无效顶层结构时停止加载,不以空状态覆盖原文件。
- 旧版程序不能读取 v15。升级前请备份;备份只保存升级时点,直接覆盖旧备份会丢失之后新增的数据,本版没有无损降级工具。
- 软删除不清除房间历史。旧章程、台账、消息、原生会话绑定和分享范围都会保留,不伪造过去的修订或验收记录。
- 导出按钮把房间写成 JSON(含完整审计历史与 SHA-256)或 Markdown(完整对话与当前台账),写入
~/.dsh/dsh-chat-local/exports/,每次生成唯一文件名、不覆盖旧备份。导出不会另行读取私聊、密钥或引用文件。
- 事件日志是附加层,
rooms.json 仍是当前读模型;日志文件位于状态目录的 events/ 子目录,可随状态目录一起单独备份。备份后用 node scripts/verify-event-log.mjs <roomId> [--state <rooms.json>] 离线校验:它逐条重算 SHA-256 链、核对头部锚点,只读、不写入,链断或尾部截断时以非零状态码退出。这个入口只校验磁盘上的日志;快照恢复走的是 verifyChain 对导入事件的校验,不经过它。
开发
npm run build # 把共享协议嵌入浏览器入口
npm run check # 生成代码一致性 + 语法检查 + 全部回归测试
npm test # 仅跑回归测试
lib/text-protocol.js 与 lib/work-protocol.js 是前后端共享的协议定义,由 lib/client.js 中的生成区块内嵌。修改协议后必须重新运行 npm run build,否则 npm run check 会因生成代码过期而失败。
提交前请确保 npm run check 全绿。当前测试覆盖房间存储、协作协议、章程与台账流程、权限拦截和 UI 组件。
scripts/ui-fixture.mjs 可在没有真实房间的情况下预览界面:它起一个 127.0.0.1:3081 的隔离服务,写入一套示例数据,并拦掉原生 Session、模型执行与真实文件访问。它借用宿主 DSH 附带的 React,因此需要 DSH_MODULES_DIR 指向 DSH 包内的 node_modules;在当前 DSH 版本上 React 已不再以独立包形式提供,脚本会以明确错误退出,尚未更新到新的模块布局。
已知边界
- 这是 DSH 的本地插件,不是 DSH 的 fork。它使用 DSH 已有的槽位、Session、模型目录和工作目录能力。升级 DSH 后应重新运行测试并复核界面——DSH 的槽位系统在 0.1.5 有过一次重构,插件对此有硬依赖。
- 房间事件保存在单机 JSON 中,不是多设备实时协作的文档。
- 事件日志是状态目录里第二份持续增长的数据集。
events/ 下的每个房间日志只追加,不轮转、不压缩、不自动清理,软删除或彻底移除房间都不会删除它的日志;它随消息、投递与每回合提示词线性增长(提示词按原样留存,是其中最大的一项)。容量、备份与保留策略由用户自行决定,本版不提供保留期、轮转或裁剪工具。
- 停滞监控只对用户明确开启监控的台账任务生效,按分钟配置,不含工作日历、免打扰时段或跨设备通知。
- 自动修改跨房间共享记忆和私信侧信道尚未开放。
- 外部历史记录只作为只读来源引用,不会自动把原群聊或私信导入新的活动时间线。
- 文件检查器提供文本预览与 DOCX 文本抽取,不含完整语法高亮、diff 或 Word 页面排版渲染。模型不得据文本抽取宣称完成了视觉审查。
许可证
MIT
更详细的领域词汇定义见 CONTEXT.md;版本变更历史见 CHANGELOG.md。