ppy-web/dsh-plugin-xiaomi-mimo-tts
ppy-web/dsh-plugin-xiaomi-mimo-tts为 DSH 提供小米 MiMo、豆包、浏览器本地 TTS 语音朗读;自动播报、自定义音色、UI 音效、桌宠联动、QQBot 联动。
会议记录插件:一个会话对应一场会议,本机离线转写与发言人分离;要点、工作安排、手写笔记、复盘与月度评分都在面板里完成。可导出 SRT/Markdown/Word,也能打成「会议工程包」(zip)在另一台 dsh 导入;已确认的工作安排按设置一键推送到钉钉/企业微信。识别模型可更换(支持从本地文件导入更强的模型),云端识别默认关闭、未同意即零请求。导出 Word 需 Python 与 python-docx;首次使用会下载识别模型(28 MB 或 77 MB)。
版本 0.1.0-preview.7(预览版)
DeepSeek Harness 的会议插件:本机转写、发言人分离、要点与工作安排、手写笔记、复盘与纪要。
音频不出本机;转写默认用随 DSH 安装的 SenseVoice,手写识别用随插件安装的本地小模型。 模型可以在「会议管理 → 模型」里换(本地更强模型,或显式同意后的云端模型)。不登录也能写字、识别、建任务、出纪要。
Output data may contain inappropriate content.)也不会影响开局;卡片没打开时由看守
(/pending)先接管再开录,不再出现「模型有时执行失败」。POST /resume。自动化冒烟 node smoke.mjs:220 项全绿(无需麦克风与模型,用临时数据目录)。
设计文档:
分支约定:
master只放发布状态(发布由标签标记,如v0.1.0-preview.6); 新功能在develop上做,稳定后再合回master并打新标签。
⚠️ 开发本插件时,工作目录必须停在
develop。 profile 里的插件目录通常是指向本仓库的 Junction/硬链接(例如~/.dsh/profiles/<名字>/node_modules/dsh-meeting-room→ 本目录), 因此你切到哪个分支,DSH 加载的就是哪个分支的代码: 切到master(只含发布修复)会让运行中的插件看起来"退回了发布版"(模型页签、云端设置都不见了), 而宿主半边每个进程只加载一次 —— 切回develop后还必须完整重启 DSH 才生效 (客户端半边刷新页面即可)。这个坑真实发生过,所以写在这里。
预览版就是要挑毛病的:发现任何问题、或想到任何改进意见,都请直接发邮件 —— 杨道泉 yangdaoquan@qq.com
信中麻烦附上:插件版本(面板「更多 → 关于」里可查)、DSH 版本、操作步骤、
以及面板上显示的错误文字或 $DSH_HOME/meeting-room/boot.log。有截图更好。
推荐用 Harness 自己的安装入口(Plugins 页,或 install_bundle / dsh plugin add),
因为它会一次把两件事都做对:写进 profile 的 dependencies,同时把包名追加进
dsh.profile.bundles。
dsh plugin --profile <你的profile名> add dsh-meeting-room
包已发布在 npm(dsh-meeting-room,国内自动走 npmmirror 镜像)。要求 DSH ≥ 0.2.0
(engines.dsh,不满足会被拦住)与 Node ≥ 20。
当前是预发布版,latest 与 preview 两个 tag 都指向它,所以上面这条按包名安装即可;
以后要用预发布线则写 dsh plugin add dsh-meeting-room@preview。
插件是否被加载,取决于 profile package.json 里的 dsh.profile.bundles,不是 dependencies。
DSH 的插件管理器就是这么工作的(@deepseek-ai/dsh-plugin-manager 的 reconcile()):
它读取 after.dsh?.profile?.bundles,把新装的包追加进去;而且只有清单里声明了
dsh.bundle 的包才算"profile 层",否则 DSH 会打印一行警告:
dsh: warning: <包名> declares no dsh.bundle — installed as a plain dependency, not a profile layer
只用 pnpm add(或任何只写 dependencies 的方式)装,插件不会被加载。 手工安装请补齐第二步:
// <profile>/package.json
{
"dependencies": { "dsh-meeting-room": "0.1.0-preview.7" },
"dsh": {
"profile": {
"bundles": ["dsh-meeting-room"] // ← 这一项才决定它被加载
}
}
}
# 1) 名字在 bundles 里
grep -n 'dsh-meeting-room' <profile>/package.json # 应出现在 dsh.profile.bundles 中
# 2) 这一层真的进了配置
dsh --profile <你的profile名> --dump-config # 应出现一层 "# == dsh-meeting-room"
# 3) 宿主代码齐全(缺 host-*.js 就是装到了旧包)
ls node_modules/dsh-meeting-room/host-*.js # 应列出 11 个
安装后需要重启 Harness:宿主半边每个进程只加载一次。
装完必须重启 Harness。宿主半边每个进程只加载一次,不重启就等于没装。
插件目录里只有几个 .js 文件 —— ...\node_modules\dsh-meeting-room\ 下只看到
index.js、client.js 与两个 worker 等少数文件,却没有 host-*.js,那么宿主半边会在
加载期就失败(index.js 引用了这些兄弟模块),表现是插件整个起不来、也没有
$DSH_HOME/meeting-room/boot.log。
这是 0.1.0-preview.1 那份包的缺陷:发布清单(package.json 的 files)漏掉了多数
host-*.js,于是打出来的包里没有宿主代码。已修复:请使用 0.1.0-preview.2 或更新的版本
(v0.1.0-preview.2 标签)。本项目还为此加了发布清单守卫(node smoke.mjs 的前几项检查):
它会遍历 index.js 等文件的相对引用,逐条核对是否被 files 覆盖 —— 同类问题不会再漏出去。
自检一行命令(在插件目录里):
ls node_modules/dsh-meeting-room/host-*.js # 应当列出 11 个 host-*.js
sherpa-onnx-node 的 peer 警告可以忽略。profile 的 pnpm 通常
autoInstallPeers: false,所以它只被记录、不被安装;插件的转写走 DSH 自带的语音能力
(ctx.get('speechToText') 懒取),缺它只影响转写,其余功能不受影响。
想消除 WARN 可显式安装:
pnpm add sherpa-onnx-node@1.13.8 # 在该 profile 目录里
插件装上了却完全不生效(Plugins 页里没有它、面板按钮不出现、dsh --dump-config 里
没有这一层)—— 最可能是只装了依赖、没进 bundles:pnpm add 只写 dependencies,
而决定加载的是 dsh.profile.bundles(见上面「为什么是两件事」)。
手工把包名加进 dsh.profile.bundles 后重启即可;用 DSH 自己的安装入口则不会踩到。
如果「开始记录」要点两次才录上,说明装的还是旧包(宿主路由缺失时,面板曾把探测失败 当成"就绪",于是第一次点击走了注定失败的直录路径)。0.1.0-preview.3 已修: 面板初始不再谎报就绪、404 不再冒充就绪、准备过程对终态与停滞都有明确出口, 并且会直接告诉你「宿主路由未注册……请更新到 0.1.0-preview.2 或更新版本」。
| 依赖 | 说明 |
|---|---|
| SenseVoice 语音识别 | 由 DSH 安装包提供(sherpa-onnx-node 声明为 peer 依赖,随安装解析;profile 若关闭 autoInstallPeers,缺它只影响转写,其余功能不受影响,见上面「安装排错」第 3 条) |
onnxruntime-node | 随本插件安装,用于手写识别。若安装时 pnpm 提示忽略其构建脚本,Windows x64 上属正常现象,模块仍可加载;其他平台如加载失败,请在该 profile 里 pnpm approve-builds 后重装 |
pinyin-pro | 随本插件安装,用于会议术语的同音订正 |
| Python + python-docx | 仅「导出 Word」需要。优先使用 DSH 运行时自带的 Python;若不含 python-docx,在其中 pip install python-docx。没有 Python 时其余功能不受影响 |
模型在首次使用时联网下载(不在包内),下载后校验大小与 sha256:
自动下载:插件会主动检查这些模型是否就绪。语音模型未就绪时:
下载源为 ModelScope 与 GitHub 代理;若全部不可达,对应功能会明确报错,其余功能不受影响。
麦克风权限:录制需要系统允许 DeepSeek Harness 访问麦克风。若点击「开始记录」后未进入录制状态,请到系统「设置 → 隐私 → 麦克风」确认已授权,并确认没有其它应用占用麦克风。
meeting_write 落库(草稿);.docx,
两者都会弹出浏览器的下载保存对话框,纪要同时留在会议里可随时打开。会议术语每行一条,三种写法:
| 写法 | 作用 |
|---|---|
错词=正确词 | 字面替换 |
陈一鸣 | 同音订正:听到「沉一明」也会改成它 |
*李 | 连单字也按同音订正(单字容易误替换,只在对某个姓氏有把握时用) |
原始转写永远保留:订正只写入 revised,界面、SRT、Markdown、纪要一律「订正优先、原文兜底」,鼠标停在句子上可看原文。
需要按上下文统一人名与错字时:用「更多 → 复制给模型订正」把实录发给模型,或直接让 Agent 用
meeting_revise 写回订正——每次订正都会留下订正对照,原文仍可追溯。
会议术语的编辑入口在「更多 → 会议术语」(内容与本机术语表同一份,边打字边保存)。
「更多 → 关于」显示本机实际安装的版本号、作者与邮箱,并可直接发邮件反馈问题或建议。
识别用哪个模型是数据,不是写死的:
内置目录就是一直以来的两个固定模型(3D-Speaker CAM++ 声纹、DAMO 手写行识别), 文件、大小、sha256、落盘目录都与以前一致,所以升级不会动你的现有安装;
想换更强的模型:下载并安装(边下边校验大小与 sha256,失败不留半个文件)、 从本地文件导入(离线机房、内网镜像、自己训练的模型都行)、启用、删除; 没装好或校验不通过不允许启用 —— 界面不会让你启用一个跑不起来的模型;
自己加模型:编辑 $DSH_HOME/meeting-room/models.json(kind/来源与镜像/文件名+大小+sha256/
目录/语言/说明/许可),页签里会列出来;写坏了会在页面上明确报错,不会被静默忽略;
会议记录会写下这场用了哪个模型,日后排查识别质量时有据可查;
页面分两栏:本地模型(按用途分组:语音识别/发言人声纹/手写识别,录音不出本机)
和云端模型(OpenAI 兼容 /audio/transcriptions,默认关闭,勾选同意才发音频);
云端一栏顶部是**「识别方式」**,三选一:
| 方式 | 行为 |
|---|---|
| 只用本地模型(默认) | 全程不进网络;即使地址、密钥都填好了也不发请求 |
| 云端优先(失败降级本地) | 每段先发云端;连续失败 3 次自动回到本地并说明原因 |
| 只用云端(不降级) | 只发云端;失败时保留本机文字并明确报错,不会悄悄用本机结果冒充云端结果 |
下面一行「当前生效:…」显示的是已保存的选择(本地/云端/已回退本地),改了下拉框 还没点保存时不会变——避免“以为已经切到云端”的错觉。
详细设计(云端接口、识别增强、分批计划)见 MODELS.md。
「会议管理 → 设置」按功能分成五个 tab,一次只展开一组,互不干扰:
| tab | 管什么 |
|---|---|
| 推送与机器人 | 推送方式(群机器人/工作通知/两者)、钉钉/企微 Webhook、钉钉应用凭据 |
| 实录与切句 | 数字规整开关、最短/最长一段、停顿阈值、静音阈值、每行字数 |
| 发言人识别 | 聚类阈值、结束录音时的全量重判、声纹库(忘记/清空) |
| 评分权重 | 质量/完成率/学习三项权重,合计必须 100% |
| 提炼模板 | 四类会议的一键提炼文案(留空用内置) |
每个 tab 各有自己的保存按钮,切 tab 不会丢掉未保存的输入。
模型(含云端识别)不在这里,见上一节:所有“用哪个模型识别”的决定都在「会议管理 → 模型」 一页里,先本地、后云端,云端默认关闭。
「会议管理 → 设置 → 实录与切句」:
二零二六年十月十九号 → 2026年10月19日、
百分之三十 → 30%、三点半 → 3点半、三千五百元 → 3500元。
这是本机规则、不联网;只改"形状",不碰人名与版本号(版本二点零 保持原样),
而且识别原文永远保留在实录里,可随时对照。规则可逐条开关(接口里的 normalizeRules)。segments(Whisper 等模型自带语义分段),
直接采用它的分段与时间,比按字符估时更准。拆分后的每一行仍带原发言人与时间范围,
数字规整、术语订正也会跟着落到每一行。「会议管理 → 设置 → 发言人识别」tab:
$DSH_HOME/meeting-room/voices.json。隐私上:向量从不出现在任何 HTTP 返回里(接口只回姓名与出现次数), 也不会被写进会议记录或工程包(落盘前剥离);「历史会议」视图下不能改姓名, 但可以勾选确认工作安排(见上)。
「会议管理 → 模型」页里的云端模型一栏是云端识别开关(和本地模型同一页,方便直接对比), 顶部「识别方式」决定本地还是云端干活:默认只用本地;选云端优先则失败 3 次自动降级; 选只用云端则失败就报错、不降级。 只有一条规矩:没有你的明确同意,一个请求都不发。
/audio/transcriptions(自建网关、各家云都能接),并在请求里声明不保留;sk-***,
会议工程包里也不会有密钥(这三条都有测试断言);asrModel)。详细设计(声纹云端接口、识别增强、分批计划)见 MODELS.md。
转写不准、断句不像人话、发言人串号,先把原因分开,不要一起调:
baseUrl=https://api.openai.com/v1、model=whisper-1(或 gpt-4o-transcribe);baseUrl=https://api.siliconflow.cn/v1、model=FunAudioLLM/SenseVoiceSmall
(以服务商文档为准,接口都是 POST {baseUrl}/audio/transcriptions);prompt 发过去;失败 3 次自动回本机。
会议记录会写下 asrModel,事后能对上是哪个模型出的字。meeting_revise 写回;订正与原文并存,随时可对照。插件装好后,技能列表里会多一个 meeting-scribe。它把「边开会边整理」串成一条流程:
meeting_session {action:"create"} 自己建会(用户说了类型才设类型,周期自动推导);meeting_session {action:"record"} 请求面板自动开始录音——麦克风仍在浏览器里,
面板几秒内自己开(第一次会询问权限);被浏览器拦住时面板会说明原因;meeting_read 读新增实录,
用 meeting_write 把要点(决定/信息/风险/待定)与工作安排(负责人、时限、原话)
写回会议,都是草稿,等你在面板确认;meeting_session 的 recording:录音一停就补齐剩余内容、
写一份会议小结、自动删除那条提醒,并告诉你共整理了多少条。record 只是请求:它不绕过浏览器权限,也不会替你点停止;你停录后它会在下一轮(≤5 分钟)收尾。manifest.json(格式与版本)、meeting.json(完整记录:实录、要点、任务、评分、
发言人标签与姓名、文档索引)、audio/<录音>、files/<纪要等产出>;importedFrom;host-package.js 用 Node 自带 zlib 直接按 ZIP 规范读写,不引入第三方依赖,
任何常规解压工具都能打开。在左侧「会议管理」页配置:
推送时按负责人分组、每人一条消息:群机器人用手机号 @人,工作通知私发给该负责人的 UserId。
通讯录同步与工作通知都需要企业内部应用具备相应权限;
user/list返回手机号还需字段权限,没有该权限时只同步到姓名与 UserId。
| 位置 | 内容 |
|---|---|
$DSH_HOME/meetings/ | 录音 WAV、导出的 SRT / Markdown / Word、手写笔记 PNG |
$DSH_HOME/meeting-room/meetings/ | 会议结构化记录(要点、任务、笔记、订正、发言人姓名),重启后自动恢复 |
$DSH_HOME/meeting-room/webhooks.json | 机器人地址、企业内部应用凭据、人员名册 |
$DSH_HOME/speech-to-text/speakers/ | 发言人模型 |
$DSH_HOME/handwriting/ | 手写识别模型 |
| 路径 | 作用 |
|---|---|
index.js | 宿主半边:事件接线(会话↔会议生命周期、归档准入)、路由注册、工具注册(meeting_read / meeting_write / meeting_note_write / meeting_revise / meeting_save_document);业务逻辑在 host-*.js |
client.js | 浏览器半边:采集、会话右侧面板、会议管理页 |
speaker-worker.js | 子进程:说话人向量提取与画廊 |
handwriting-worker.js | 子进程:本地手写识别 |
host-package.js | 会议工程包的打包与导入(ZIP 读写只用 Node 自带 zlib) |
smoke.mjs | 发布前自动化冒烟:node smoke.mjs |
TESTING.md | 发布前系统化测试清单(自动化 + 手动 A–Q 组) |
minutes-docx.py | 用 python-docx 把纪要渲染成 Word |
cordis.patch.yml | 组合包 patch,把宿主行插进 profile 层栈 |
tools/recognize-note.mjs | 开发工具:对一张手写 PNG 直接跑识别 |
本插件由博尔塔拉融媒体中心媒体传播与认知重点实验室制作。
MIT,全文见 LICENSE:
Copyright (c) 2026 博尔塔拉融媒体中心媒体传播与认知重点实验室(杨道泉)
也就是说:可以自由使用、修改、再分发(含商用与机构内部部署),只需保留版权与许可声明; 软件按"现状"提供,不含担保。
本插件调用的第三方组件与运行时下载的模型(onnxruntime-node、pinyin-pro、sherpa-onnx-node、 3D-Speaker CAM++ 声纹模型、DAMO 手写模型等)各自适用其作者的条款,来源与校验值见 THIRD-PARTY-NOTICES.md。