dsh-interject:在下一步边界送达排队消息,不打断当前模型调用

前言

在 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 后重发」之间选择;本插件默认走前者,通过队列迁移实现「尽早可见」。

核心功能

  1. 默认策略不 interrupt:配置默认 onQueue: "steer",将进入 next-turn 的用户消息提升为 next-step;onSteer: "pass" 表示已进入 next-step 的消息按宿主语义在下一边界生效。默认不会产生额外模型请求,只是把 pending 消息换队列;消息更早进入 history 后,本 turn 剩余请求会多携带一次前缀,README 称这通常对应 prompt cache,成本很低。只有显式使用 interrupt 路径才会因 abort 产生额外计费。

  2. 可配置 interrupt 与降级:可将 onSteer 设为 interrupt,使 Cmd/Ctrl+Enter 成为抢占手势;interruptWhile 为 thinking 时,工具运行阶段的长命令会降级为 soft interject 而非硬杀进程。

  3. 能力探测而非硬依赖:插件不 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 等版本上逐项核对过所用公开面。

  4. 热重载配置:修改 ~/.dsh/dsh-interject.json 保存即生效,无需重启;修改 lib/index.js 或安装插件后需完全重启 DSH(插件以静态 ESM 加载,运行中改文件不生效)。

  5. 诊断与自检:可选日志、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。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye