🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

回合插话 blueberrymaid/dsh-midtalk

DeepSeek Harness
blueberrymaid41 天前有提交已提供中文文档扫描:含敏感能力

运行中无损插话,或中止当前步并留下恢复卡

29.6/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/28 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add blueberrymaid/dsh-midtalk
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/09/28·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/05·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 41 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 8 处,展示前 6 条)
  • 写入本地文件
    index.js:68
    mkdirSync(RECOVERY_DIR, { recursive: true });
  • 写入本地文件
    index.js:70
    writeFileSync(
  • 写入本地文件
    index.js:75
    renameSync(tmp, BOOT_FILE);
  • 写入本地文件
    index.js:83
    mkdirSync(RECOVERY_DIR, { recursive: true });
  • 写入本地文件
    index.js:84
    appendFileSync(WAKE_LOG, `${JSON.stringify(entry)}\n`, "utf8");
  • 写入本地文件
    index.js:96
    mkdirSync(RECOVERY_DIR, { recursive: true });
扫描于 2026/11/5(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-llm
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 运行中无损插话
  • 中止当前步
  • 留下恢复卡

给正在跑的回合插话:/say 无损,/cut 中止当前步并留下恢复卡。

README

由 DeepSeek 最新模型翻译生成
dsh-midtalk 任务内插话 + 可选打断 + 结构化恢复卡——给 DeepSeek Harness(DSH)加两条斜杠命令,把“我中途想说一句”和“我要立刻停住这一步”分开,并且打断的时候不丢现场。 English · 中文 - 纯 host 侧插件(Cordis),零客户端代码、零构建、无第三方运行时依赖;对宿主包 @deepseek-ai/dsh-llm 有一个 peer 依赖——只有 index.js 用它来构造注入消息,lib/core.js 与自测都不需要它。 - 不注册任何模型能力、不联网、不上报任何数据;只在 $DSH_HOME/midtalk/ 下写自己的启动标记、送话日志与恢复卡。 - 不经 npm 分发:package.json 里 "private": true,装法是“把目录放进 profile”(见 §3),不是 npm i。 1. 它解决什么问题 任务进行中你想插一句话,本来只有两个极端: | 做法 | 代价 | | 等这一轮跑完再说 | 慢,而且长步骤可能几分钟 | | 按界面停止按钮 | 立刻,但当前这一步被砍掉,可能留下半截状态,且你刚才那句话没人接 | 本插件把这两件事拆成两条命令,由你按一次回车来决定,不做任何“智能升格”(不按步长自动改成打断——这条是明确的设计选择,理由见 §6)。
展开完整文档(README 剩余 1 节)
dsh-midtalk

任务内插话 + 可选打断 + 结构化恢复卡——给 DeepSeek Harness(DSH)加两条斜杠命令,把“我中途想说一句”和“我要立刻停住这一步”分开,并且打断的时候不丢现场。

English · 中文

- 纯 host 侧插件(Cordis),零客户端代码、零构建、无第三方运行时依赖;对宿主包 @deepseek-ai/dsh-llm 有一个 peer 依赖——只有 index.js 用它来构造注入消息,lib/core.js 与自测都不需要它。
- 不注册任何模型能力、不联网、不上报任何数据;只在 $DSH_HOME/midtalk/ 下写自己的启动标记、送话日志与恢复卡。
- 不经 npm 分发:package.json 里 "private": true,装法是“把目录放进 profile”(见 §3),不是 npm i。

1. 它解决什么问题

任务进行中你想插一句话,本来只有两个极端:

| 做法 | 代价 |
| 等这一轮跑完再说 | 慢,而且长步骤可能几分钟 |
| 按界面停止按钮 | 立刻,但当前这一步被砍掉,可能留下半截状态,且你刚才那句话没人接 |

本插件把这两件事拆成两条命令,由你按一次回车来决定,不做任何“智能升格”(不按步长自动改成打断——这条是明确的设计选择,理由见 §6)。

2. 两条命令

| | /say | /cut [你要说的话] |
| 语义 | 无损:插到下一个步骤边界 | 有损:中止当前这一步 |
| 打断? | 不打断 | 打断(在跑的工具调用被取消) |
| 延迟 | = 当前这一步的剩余时长(步很短就几乎立刻;步很长就一直等) | 等 agent 回到 idle 再送话,兜底 3 秒(本机一次观测 27 ms,取证见 $DSH_HOME/midtalk/wake.log) |
| 轮次 | 留在同一轮里回应 | 当前轮结束,你的话作为新一轮到达 |
| 残余状态 | 没有 | 可能有(被打断的那一步) |
| 恢复 | 不需要 | 自动写一张结构化恢复卡 |
| 什么时候用 | 默认就用它 | 我卡在一个很长的步骤里、你必须现在停我 |

两条命令的返回文本都会附一句「最近一个工具调用开始于 X 秒前(估量)」——只给信息,不改语义:你看一眼就知道该不该改用 /cut。

3. 安装

本插件在 package.json 里声明了 dsh.bundle.patch(指向仓库根的 cordis.patch.yml),所以 DSH 自带的插件命令能把它按图层装进某个 profile;也完全可以手工放进去(方式 B)。

两个文件必须一起在包里:index.js 与 lib/core.js——index.js:44 是对 ./lib/core.js 的相对导入,少一个就挂载失败。

方式 A:dsh plugin add(推荐,需要重启 DSH)

dsh plugin --profile web add "github:blueberrymaid/dsh-midtalk"

这是 pnpm 的薄转发(@deepseek-ai/dsh/lib/plugin-Ddi42qoW.js:7-17):它在 profile 目录里跑 pnpm add ,然后按已安装状态核对 profile 的图层列表——某个依赖解析到的包若声明了 dsh.bundle,就被加进 dsh.profile.bundles;否则只当普通依赖装下并给一句警告(:25-33、:46-78)。所以 package.json 里的 dsh.bundle.patch 不是装饰:没有它,插件装上了也不会成为 profile 图层。装完重启 dsh web 生效。

方式 B:手放目录 + 名册(不依赖 pnpm / 网络)

第 1 步:放到模块目录

从 GitHub 取
git clone https://github.com/blueberrymaid/dsh-midtalk.git dsh-midtalk

把整个目录(至少 index.js + lib/core.js)放进:

$DSH_HOME/profiles//node_modules/dsh-midtalk/

$DSH_HOME 默认是用户主目录下的 .dsh;Windows 上实际路径形如 C:\Users\\.dsh\profiles\web\node_modules\dsh-midtalk\(profile 名通常是 web,在你自己的机器上以 $DSH_HOME\profiles\ 下的目录名为准)。

第 2 步:挂上名册

在 $DSH_HOME/profiles//cordis.patch.yml 里加一行 insert:

- insert:
- id: midtalk
name: dsh-midtalk

改之前先备份该文件(例如 Copy-Item cordis.patch.yml cordis.patch.yml.bak)。这个文件是启动时一次性读取、全或全无:写坏一行会让 dsh web 整个起不来。

name 也接受相对/绝对路径写法(例如 ./node_modules/dsh-midtalk/index.js)。

第 3 步:重启 dsh web,然后做下面的确认。

怎么确认装上了

读 $DSH_HOME/midtalk/boot.json——插件在 apply() 与命令注册完成时各写一次(index.js:210、index.js:235):

{ "plugin": "dsh-midtalk", "version": "1.0.0", "stage": "registered", "commands": ["say", "cut"], "pid": 18092 }

- version 必须等于你装的版本;stage 走到 registered 才算命令注册完成。
- pid 是写下该文件的进程。版本没变或 stage 停在 apply,说明活进程跑的不是你刚放进去的代码——ESM 模块缓存会喂回旧版本,重启最能保证清掉它。
- GUI 输入 / 时应能看到 /say 与 /cut。
附录:免重启方式(dsh-my-guardian 候选区,本机实测)

装了 dsh-my-guardian 的机器可以改候选文件让它热挂载、不重启。下面是作者本机实测过的流程,不是通用要求:

1. 把包放进 $DSH_HOME/profiles/web/node_modules/dsh-midtalk/;
2. 往 $DSH_HOME/profiles/web/cordis.staged.json 写一行:
[{"id":"midtalk","name":"./node_modules/dsh-midtalk/index.js?v=1"}]

3. 几秒内 guardian 会试挂:成功即从候选文件移除、并把条目写进 $DSH_HOME/guardian/state.json 的 promoted;失败会保留候选行并在 lastError 里给原因(连续失败 3 次会冻结)。

两条实测出来的坑:

- 换模块名必须同时换 id:只换 name、沿用旧 id,guardian 完全不受理(候选行原样留着、不报错、不挂载)。
- 同一个路径重挂不会换代码:ESM 模块缓存会让活进程继续跑旧代码(实测:dsh-progress-report 三次安装零生效)。跳过缓存只有一个杠杆——给模块名加查询串,如 ?v=2;再用 boot.json 的 version 核对。

卸载 / 回滚

1. 从 cordis.patch.yml 删掉那行 insert(guardian 环境里也可以 POST http://127.0.0.1:3080/guardian/api/remove,body {"id":""},立即热卸载);
2. 删掉 $DSH_HOME/profiles//node_modules/dsh-midtalk/;
3. 可选:删 $DSH_HOME/midtalk/(内含 boot.json、wake.log、last-interrupt-*.json 恢复卡——想留就留,它们是纯文本)。

4. 恢复卡

/cut 在打断前把现场写到 $DSH_HOME/midtalk/last-interrupt-.json(每个会话一张,不会互相覆盖;原子落盘:临时文件 + 同目录 rename,所以不会出现半截 JSON)。字段:

| 字段 | 含义 |
| at / reason | 时间 / 触发原因(cut) |
| plugin / version | 写入者与版本(用来判断"活进程跑的是哪一版") |
| agentStatus / sessionId | 打断时的 agent 状态与会话 |
| interruptedAt | {turn, step, attemptId}——被打断的位置 |
| userText | 你附带的那句话 |
| pendingToolCalls | 正在派发/刚派发的工具调用:{at, attemptId, callId, name, arguments}(arguments 已解析成对象,不是转义字符串) |
| lastReasoning / lastText | 我被打断前的推理/正文片段(各截 2000 字符) |
| usage / lastFinish | 那一刻的 token 用量与结束原因 |
| diagnostics | 帧类型计数、解析失败数——出问题时用它判断帧格式是否变了 |
| frames | 最近 12 个流帧(环形窗口,便于回看现场) |

恢复协议(打断后照做,只依赖这张卡,不需要别的文件):

1. 先列状态、不继续干;
2. 读这张卡,重点是 pendingToolCalls:它列出被打断那一刻正在派发/刚派发的工具调用(名字 + 参数);
3. 逐个判断"是否已落地"——卡里给的是调用意图,不是落地清单,所以要自己核实它碰的文件/命令(读文件、看退出码、比对修改时间);
4. 把判断结果(已落地 / 需回滚 / 先验证)交用户拍板;
5. 用户确认后重做被打断的那一步。

理由:agent.cancel 不会撤销已经落地的写入。

5. 硬规则行(只进插件)

两条命令注入的正文末尾都带一行:

〔硬规则 · 收到插话先输出一句正文回复(确认收到 + 回应内容),再决定是否继续调用工具;只发工具调用、或不回话=违规〕

它写死在 lib/core.js:16,不进宿主每轮注入的 AGENTS.md:这是本插件自己的行为约束,不该污染全局。出处是一次真实事故:收到插话后只发工具调用、不写正文,用户连问两次都没得到回应。它是文本约束,没有执行层强制力——但至少让"被问到却不回话"变成明确违规,而不是风格问题。

6. 它不做的事(故意的)

- 不杀后台:jobs.kill / terminals.kill / subagents.interrupt / goals.disarm 一个都没接。杀后台本身就会制造半截状态(正在下载、正在写文件的活),与本插件"不丢现场"的目标冲突。
- 不做阈值自动升格:不去看"当前步跑了多久然后自动改成打断"。那会把你唯一的保证(/say 永不破坏)变成由你看不见的状态决定的条件保证,还剥夺你的选择权。
- 不隐藏括号内容:注入正文里的行为说明会显示为系统行(source: {kind:"plugin", form:"notice"}),不是伪装成你的消息,但看得见。想彻底隐形需要不被渲染的通道,本插件做不到。
- 不撤销已落地的写入(系统层没有回滚这一说)。

7. 依赖的未公开内部接口

本插件的功能建立在 DSH 的内部事件与 API 形状上。下面每一行都在源码里核对过;实测 DSH 版本:@deepseek-ai/dsh 0.1.5-rc.3、@deepseek-ai/dsh-llm 0.1.5-rc.3(版本号读自这两个包的 package.json:4)。升级 DSH 后这些接口都可能变,一变本插件就静默失效(不会有编译错误,因为它是动态挂载的 JS)。

| 用途 | 依据(包名 + 文件:行) |
| 无损投递 | agent.steer(createUserMessage(...));createUserMessage 来自 @deepseek-ai/dsh-llm(index.js:25 的顶层 import,index.js:177 使用) |
| 有损投递 | agent.cancel({kind:"user"}, {keepInbox:true}),与界面停止按钮同一调用:@deepseek-ai/dsh-api-session-controller/lib/index.js:872-878(本插件在 index.js:198 调它) |
| 送话时机 | agent.status getter(idle | maintenance 之外都算 running):@deepseek-ai/dsh-agent-loop/lib/index.js:773-775;状态变化时发 agent/status:同文件 :776-782;事件载荷带 agent:@deepseek-ai/dsh-tool-cordis/lib/index.js:5061-5065 |
| 恢复卡内容 | agent/assistant-stream 帧(订阅在 index.js:211);frame.chunk 是对象(StreamChunk)而不是字符串(lib/core.js:65-70 兼容两种) |
| 系统行显示 | source: {kind:"plugin", plugin, form:"notice", summary}(样板:@deepseek-ai/dsh-agent/lib/index.js:99-114;本插件在 index.js:148-153) |
| 命令注册 | ctx.commands.register({name, description, input, handler}):@deepseek-ai/dsh-commands/lib/index.js:257-259;重名会抛错:同文件 :82(且没有公开的 unregister API——换版本要先卸载旧插件腾出命令名) |
| 命令调用载荷 | handler 收到 {agent, rawInput, ...}(本插件 index.js:166-171) |

8. 已知边界

- /say 的延迟 = 当前这一步的剩余时长:我跑一个 100 秒的单步,你就会 100 秒收不到回应(实测过;对策是把长活拆成短步,或改用 /cut)。
- 待送话队列上限 8,超出会静默丢最早的:MAX_PENDING_WAKES = 8(lib/core.js:20)。同一个 agent 堆积超过 8 条待送话时,最早的会被丢弃(index.js:132-143),只在 $DSH_HOME/midtalk/wake.log 留一行 "why":"dropped:queue-full"——不会提示用户。正常用法(一次一条 /cut)碰不到,连续快速 /cut 才会。
- 恢复卡给的是工具调用的意图,不是“是否已落地”的清单——后者结构上拿不到,靠流程兜(原子写入、只碰可整体删除的容器)。
- 一步里超过 20 个工具调用时只保留最后 20 条(lib/core.js:26)。
- lastText / lastReasoning 各截 2000 字符(lib/core.js:24-25),frames 环形窗口只有 12 帧(lib/core.js:21)。
- 空 /say(不带内容)会注入一条无内容的插话。
- 兼容性只在实测 DSH 版本(0.1.5-rc.3)上验证过:2026-09-25,Windows + node 22。Linux / macOS 未实测(代码里没有平台相关分支,但没跑过)。

9. 开发

dsh-midtalk/
├── index.js 宿主半边:命令注册、cancel、写盘、事件订阅 ├── lib/core.js 纯逻辑:流帧→trace、trace→恢复卡对象、正文拼装(零依赖,自测只跑这一层) ├── test/plugin.spec.mjs 自测(零框架,只用 node 内置模块) ├── .github/workflows/test.yml CI:ubuntu-latest + windows-latest × node 22 ├── .gitignore / .gitattributes ├── cordis.patch.yml dsh.bundle.patch 指向的图层补丁(方式 A 靠它安装) ├── package.json ├── README.md / README.en.md └── CHANGELOG.md / LICENSE

node test/plugin.spec.mjs # dsh-midtalk 自测:38 passed, 0 failed

自测只覆盖 lib/core.js(不 import DSH 包、不碰文件系统、不写 .dsh),所以在任何地方、任何平台都能跑,也不需要 npm install。

10. License

MIT(见 LICENSE)。
预览分享卡片长什么样 ↓blueberrymaid/dsh-midtalk
分享 · DeepSeek Harness Hub
blueberrymaid/dsh-midtalk

运行中无损插话,或中止当前步并留下恢复卡

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部