前言¶
在 DeepSeek Harness(DSH)里跑智能体时,一个 turn 往往包含多步:每一步对应一次模型调用及其工具执行,单步推理也可能持续数分钟。你在 Agent 忙碌期间通过「排队并发送」输入的内容,会进入 inbox 的 next-turn 队列;宿主默认要在整轮 turn 全部结束之后才会认领这条消息。若 turn 很长,你的补充说明会长时间滞留在队列里,模型在后续步骤里看不到。
下面介绍社区插件 dsh-interject(维护者 sdlhs,分类:工作流)。它在不终止、不丢弃当前正在进行的模型请求的前提下,把符合条件的排队消息提前挪到 next-step 队列,从而在下一个 step 边界进入对话历史——而不是干等整轮结束。插件只挂载 DSH 宿主侧,不改客户端、不改 WebUI、不涉及 app.asar。
这是什么¶
dsh-interject 是 DSH host plugin(当前 package 版本 0.3.0,MIT 许可证)。它监听 agent/inbox/inserted,在策略匹配时把消息从 next-turn 移到 next-step;下一步开始时模型会在 history 里看到你的输入,正在 flight 中的推理不会被 abort。
DSH inbox 有两条队列,行为对比如下:
| 队列 | 典型写入方式 | 何时被认领 |
|---|---|---|
next-turn |
忙碌时「排队并发送」 | 整轮 turn 结束之后 |
next-step |
Cmd/Ctrl+Enter(插话并发送) | 下一个 step 边界(一步 = 一次模型调用 + 其工具) |
README 说明:llm.stream(request) 在构建请求时冻结 messages 数组,HTTP 体发出后无法在生成中途追加输入,因此只能在「等当前调用结束」与「interrupt 后重发」之间选择;本插件默认走前者,通过队列迁移实现「尽早可见」。
核心功能¶
-
默认策略不 interrupt:配置默认
onQueue: "steer",将进入next-turn的用户消息提升为next-step;onSteer: "pass"表示已进入next-step的消息按宿主语义在下一边界生效。默认不会产生额外模型请求,只是把 pending 消息换队列;消息更早进入 history 后,本 turn 剩余请求会多携带一次前缀,README 称这通常对应 prompt cache,成本很低。只有显式使用interrupt路径才会因 abort 产生额外计费。 -
可配置 interrupt 与降级:可将
onSteer设为interrupt,使 Cmd/Ctrl+Enter 成为抢占手势;interruptWhile为thinking时,工具运行阶段的长命令会降级为 soft interject 而非硬杀进程。 -
能力探测而非硬依赖:插件不 import
@deepseek-ai/*,仅使用宿主传入的ctx/agent对象;文档声明兼容>=0.2.0-rc.1,并在0.2.0-rc.2、0.2.1-rc.5、0.2.2-alpha.2等版本上逐项核对过所用公开面。 -
热重载配置:修改
~/.dsh/dsh-interject.json保存即生效,无需重启;修改lib/index.js或安装插件后需完全重启 DSH(插件以静态 ESM 加载,运行中改文件不生效)。 -
诊断与自检:可选日志、
bootMarker写入~/.dsh/dsh-interject-boot.json;仓库提供离线node test/test-interject.mjs与node test/test-interject-loop.mjs自测(无需启动 DSH)。
安装与启用¶
从插件市场¶
在 DSH 插件市场中搜索 dsh-interject 安装;市场会从 GitHub 仓库解析包。社区目录页:https://www.skillhub.cn/plugins/sdlhs/dsh-interject(独立社区站点,与 DeepSeek / 幻方无官方从属关系)。
从源码目录安装¶
若已有仓库源码目录,在插件根目录执行(资料原文):
dsh plugin --profile desktop add .
包声明了 dsh.bundle.patch,profile 会自动拾取 cordis.patch.yml,下次启动时挂载。安装或编辑 lib/index.js 后请完全重启 DSH。
手动挂载(不用市场)¶
在 profile 的 cordis.patch.yml 中增加:
- insert:
- id: dsh-interject
name: dsh-interject
name 必须是包名,不要写绝对路径,否则插件卡片可能显示「已安装但未加载」。
配置与验证¶
配置文件路径:~/.dsh/dsh-interject.json(热重载)。默认值示例(字段含义见 README 表格):
{
"enabled": true,
"onQueue": "steer",
"onSteer": "pass",
"interruptWhile": "thinking",
"graceMs": 250,
"cooldownMs": 2000,
"includeSubagents": false,
"stallMs": 120000,
"wakeFallbackMs": 3000,
"bootMarker": true,
"log": true
}
关闭插件:{"enabled": false}。要让 Cmd/Ctrl+Enter 走抢占:{"onSteer": "interrupt"}。
环境变量可覆盖路径:DSH_INTERJECT_CONFIG、DSH_INTERJECT_LOG(空字符串关闭日志)、DSH_INTERJECT_BOOT。
验证 promotion 是否发生:查看日志尾部,成功时会记录 next-turn -> next-step <id>。Windows 示例如下:
Get-Content "$env:TEMP\dsh-interject.log" -Tail 20
确认当前进程加载的构建版本(重启后是否生效):
Get-Content "$env:USERPROFILE\.dsh\dsh-interject-boot.json"
其中 version 为运行中进程实际加载的版本;pid 应对应当前 DSH 进程。
适用场景与注意¶
适合:长 turn、多步工具链场景下,你希望在下一步就让模型看到排队说明,又不愿 interrupt 浪费已生成的输出与 token。
局限(资料原文):
steer不是零延迟:只能在本轮模型调用的边界生效;若单次调用跑十分钟,仍需等到该调用结束。- 移动消息会产生一条
agent/inbox/spliced且outcome: 'canceled',属公开 API 形状,文档称对 goal driver 与 UI 无害。 - 插件以当前 DSH 进程权限运行;安装前请自行审阅 源码与许可证,勿在未信任的来源安装宿主插件。
结尾¶
dsh-interject 解决的是「忙碌期间排队消息要等到整轮 turn 结束才进 history」的时序问题:通过 inbox 队列迁移,在下一步边界送达输入,默认不打断正在跑的模型调用。详情与 issue 见 GitHub:https://github.com/sdlhs/dsh-interject;目录介绍见 SkillHub:https://www.skillhub.cn/plugins/sdlhs/dsh-interject。