dsh
OpenPetsHQ/openpets将 DeepSeek Harness 的生命周期状态、错误与审批请求,桥接到本地运行的 OpenPets 桌面伙伴。
回合提醒音乐:对话(回合)结束时播放铃声或任意本地音频提醒你回来——内置合成的电话「叮铃铃」,也可填宿主机绝对路径或直接在设置页上传;右下角浮标可暂停/继续/关闭,默认循环响到你手动停;设置项在「设置 → 内置插件」里,部署级默认值可写进 cordis.patch.yml。
DeepSeek Harness 的回合提醒音乐:对话(回合)结束时自动响起音乐,把离开屏幕的你叫回来。内置电话「叮铃铃」铃声,可在设置里开关、改路径或直接上传音频,右下角浮标随时暂停。
Turn-finished music reminder for DeepSeek Harness Web: a chime/ringtone (bundled telephone ring, or any local audio file, or an upload) plays when the agent finishes a turn, with an in-page chip to pause/dismiss.
Agent 跑长任务时你走开了,回来才发现它十分钟前就答完了。这个插件在回合结束的那一刻播放一段音乐,一直响到你点暂停;声音在浏览器里播,所以手机、笔记本、远程访问的页面都能听见。
回合开始 → (你走开)→ 回合结束 → 🔊 叮铃铃 + 右下角浮标「⏸ 暂停 / ✕」
running 由 true 变 false),不依赖模型自我提醒,也不占用 API 调用。ask_user_question)或等你点审批时,回合其实还在 running,单纯等回合结束会一直静默;插件同时监听 uiSession.sessionStatus 的 pendingInteraction,交互一出现就响。设置 → 内置插件 → 回合提醒音乐,同一张卡片也出现在左侧插件面板里。~),或直接在卡片里选文件上传(远程访问也能用)。scripts/make-ringtone.py),装完即响,不需要准备任何音频。cordis.patch.yml(部署级),个人设置在设置页覆盖,所有会话、所有项目共用一份。npm i 即用。dsh plugin --profile web add dsh-turn-music
装完重启一次 dsh web(或在插件面板里触发一次重载),刷新页面即可。
从 GitHub 装(未发布到 npm 时的备用来源):
dsh plugin --profile web add github:ramwin/dsh-turn-music
设置 → 内置插件 → 回合提醒音乐(或左侧栏「插件」面板里的同名卡片)。浏览器自动播放:浏览器要求页面至少被点过一次才允许出声。你正常用 GUI 打字/点按钮就已经满足;如果第一时间没声音,浮标会显示「浏览器拦截了自动播放,点一下播放」,点它即可。
| 设置 | 默认 | 说明 |
|---|---|---|
| 启用 | 开 | 回合结束时是否播放 |
| 音乐文件 | 空 | 留空 = 内置叮铃铃;填 ~ 或绝对路径;也可上传 |
| 音量 | 80 | 0–100,滑杆步进 1%,只影响本插件的播放 |
| 循环播放 | 开 | 一直响到你手动暂停/关闭(关掉则播完一遍就停) |
| 最长响多久 | 120 秒 | 循环时的安全上限,0 = 不限 |
| 只提醒当前会话 | 关 | 开:只对屏幕上正在看的会话响 |
| 忽略子代理会话 | 开 | 子代理与团队子任务的回合结束不响(团队子任务始终静音) |
| 提问/审批也提醒 | 开 | 模型弹出选择题或等你审批时播放(同一去重、onlyCurrent、子代理规则) |
设置存在 ~/.dsh/turn-music.json(全局,不分项目/会话);上传的音频存在 ~/.dsh/turn-music/;播放位置存在 ~/.dsh/turn-music-position.json(按音频文件的 mtime 记账,换歌自动归零)。
在 profile 的 cordis.patch.yml 里给插件条目写 config,它成为默认值(个人设置仍可覆盖,「恢复默认」回到这里):
- id: turn-music
name: 'dsh-turn-music'
config:
enabled: true
file: /srv/sounds/ring.mp3
volume: 80
loop: true
maxSeconds: 120
onlyCurrent: false
muteSubagent: true
onQuestion: true
浏览器 宿主进程
──────────────────────────────────── ─────────────────────────────
sessions.list 快照
running: true → false ──┐
├─► <audio src=/dsh-turn-music/audio>
GET /dsh-turn-music/config ┘ ├─ 读 ~/.dsh/turn-music.json
POST /dsh-turn-music/config ────────────────►├─ 校验并落盘
POST /dsh-turn-music/upload ────────────────►└─ 存 ~/.dsh/turn-music/ringtone.*
sessions.list 是客户端会话列表 store(running 由 true 变 false = 回合结束),uiSession.sessionStatus 的 pendingInteraction = 有提问或审批挂起(此时 running 仍是 true);也只有页面能把声音放出来。宿主进程在服务器上,没有扬声器。Range),所以远程打开页面、甚至手机访问,都能播出本机上的那个文件。选择题弹出来为什么不响? 提问和审批发生在回合进行中(running 仍为 true),回合结束那条边沿等不到它们。插件为此单独监听 uiSession.sessionStatus 的 pendingInteraction:开关在设置里的「提问/审批也提醒」(默认开)。若关掉它、或默认「忽略子代理会话」(子代理的提问静音)、或开了「只提醒当前会话」而提问在别的会话,都不会响。
没声音? 先看浮标:显示「浏览器拦截了自动播放」就点一下;否则检查设置里的音量与「启用」,以及文件路径是否还存在(宿主会自动回退到内置铃声)。
多个标签页同时开着? 每个页面都会响一次。需要单窗口行为的话,关掉其他标签页即可(这点与音乐播放器不同,后续可按需加跨窗口去重)。
团队模式(Agent Teams)下为什么子任务完成不响? 团队跑起来以后,Lead 会在等成员时多次结束回合,成员完成一个子任务也只是整个流程中的一步——这时候响会误报。插件同时适配两种团队实现:
agentTeam 投影,只要还有 in_progress 任务、或还有成员会话在跑,就不响;@nanmicoder/dsh-agent-teams:读它的 /plugins/dsh-agent-teams/state 快照,团队还有没收尾的任务(未 completed / failed / cancelled)或有成员在 working,就不响。两种情况都是整个团队收尾后 Lead 的最后一次回合结束才提醒;团队停在 staged 等审批、或已经没有在跑的任务时,仍会正常提醒。
刷新/重启后设置还在吗? 在。设置在宿主侧 ~/.dsh/turn-music.json,不依赖浏览器 localStorage。
能不能播放网络音频? 目前只支持本机文件与上传。在线电台/音乐建议配 dsh-music-player。
安全边界:/dsh-turn-music/* 走 dsh 自己的登录态;能读到的只是被配置的那一个音频文件(或上传目录),不做任意路径列举。
npm test # host 侧校验逻辑 + 浏览器侧回合检测逻辑(无 jsdom)
需要一个独立实例做端到端验证(会真的跑一轮模型回复,别对着正在用的宿主跑):
dsh web --port 3099 --no-open --host 127.0.0.1 > /tmp/boot.log 2>&1 &
TOKEN=$(grep -o 'token=[A-Za-z0-9_-]*' /tmp/boot.log | head -1 | cut -d= -f2)
node scripts/verify-browser.mjs "http://127.0.0.1:3099/?token=$TOKEN" # 客户端 half 是否加载、浮标是否创建
node scripts/verify-turn.mjs "http://127.0.0.1:3099/?token=$TOKEN" # 真发一条消息,等回合结束,断言浮标亮起+暂停可用
重新生成内置铃声(需要 ffmpeg):
python3 scripts/make-ringtone.py assets/ringtone.mp3
MIT。内置铃声由 scripts/make-ringtone.py 纯数学合成,不涉第三方素材,随包按 CC0 使用。