前言¶
DeepSeek Harness(DSH)的会话是「一次一步」推进的:某个工具调用在前台跑多久,整轮对话就停多久。Agent 执行 bash({ command: "sleep 60" }) 会把会话冻住一分钟;长时间 wait_agent 同理。DSH 对超时较慢的「工作型」命令有 promote 到后台作业的兜底,但先要耗完 timeout,而纯等待并不是工作。
在工作区里写 AGENTS.md 或给每个 preset 复制规则,新工作区容易漏配。维护者 JJJACKsong 的 sleep-not-permitted 是 profile 级 DSH 插件(npm 包名 dsh-plugin-sleep-not-permitted,当前目录页标注 v0.4.0),装一次后对所有工作区、会话与子代理生效,用系统提示预防 + 工具守卫拒绝,把等待改写成后台作业或结束本轮等待完成通知。
这是什么¶
sleep-not-permitted 是 DeepSeek Harness 的 Cordis 宿主插件:禁止 Agent 在前台「干等」。当模型尝试 sleep、wait、tail -f、watch、无 -c 的 ping、无限循环等命令,或调用超过预算的阻塞等待工具(wait_agent、job_output 且 wait: true)时,调用会被同步拒绝;拒绝原因里写明应使用 run_in_background: true,或结束本轮由作业完成通知唤醒。
守卫不会偷偷改写工具参数——DSH 在分发前会记录并展示参数,插件只能拒绝、不能伪装成另一次调用。
- 维护者:JJJACKsong
- 分类:工作流(SkillHub 目录)
- 仓库:https://github.com/JJJACKsong/sleep-not-permitted
- 许可证:MIT(见仓库
LICENSE)
核心功能¶
下面按 README 已说明的行为归纳,不做超出文档的扩展。
预防与 enforcement¶
- 事前预防:在系统提示中紧贴「后台作业」段落写入同一条规则(
announceInPrompt: true时),引导模型优先选后台形态。 - 事后门禁:若仍以前台形式调用,通过
ctx.tools.guard()同步拒绝,错误信息中包含可照抄的重试方式。
会被拦截的内容¶
等待型 shell 命令(默认作用于 bash、pwsh、terminal_send):sleep、wait、tail -f / -F、watch、无 -c 的 ping、yes、while true 类无限循环,以及 docker logs -f、journalctl -f、kubectl logs -f 等跟随日志。引号内的字面量不算命中(例如 echo "sleep 30" 放行)。
阻塞等待工具:wait_agent,以及 job_output 在 wait: true 且请求等待超过 maxBlockingWaitMs(默认 30000 毫秒)时。设为 0 可进入严格模式:任意前台等待一律拒绝。
轮询:在 pollWindowMs(默认 120000)内同一检查命令出现超过 pollRepeatThreshold(默认 3)次时拒绝,避免用「睡一下再 check」代替正式等待。
交互式 / 需人工确认的命令(interactiveGuard: true 时):如不带 -n 的 sudo、不带 BatchMode 的 ssh、vim / less / top、docker run -it、npm login 等。这类命令在后台也会被拒——后台作业无 stdin,会静默挂住。
已带 run_in_background: true 的调用放行(后台作业内的 sleep 允许)。普通命令、ask_user_question、不带 wait 的 job_output 等不受影响。
外部等待的正确写法¶
若等待对象没有本地 DSH job 句柄(远端主机、外部服务),应把「等待本身」包进后台作业,例如:
ssh host 'until [ -f done ]; do sleep 5; done'
并对该 bash 调用设置 run_in_background: true,然后结束本轮;作业完成后由通知唤醒,再用 job_output 读结果。完成通知只表示作业结束,不代表成功,需根据 completed / failed / killed 与 exit code 再决策。
安装与启用¶
插件以标准 DSH bundle 形式挂载(dsh.bundle.patch → cordis.patch.yml)。SkillHub 目录页的说明是:请安装 DSH 插件 JJJACKsong/sleep-not-permitted(可在 DSH 内让插件管理器读取该标识完成安装)。
README 给出的 web profile 预构建包安装示例(无需本地构建)如下;路径中的版本与 release 文件名以文档原文为准:
dsh plugin --profile web add https://github.com/JJJACKsong/sleep-not-permitted/releases/download/v0.1.0/dsh-plugin-sleep-not-permitted-0.1.0.tgz
若已有插件目录的绝对路径,也可:
dsh plugin --profile web add /path/to/sleep-not-permitted
Electron desktop profile 需用会话内 plugin_manager 的 install_bundle,target 传目录绝对路径(详见 README「安装 / 卸载」)。
卸载 web profile:
dsh plugin --profile web remove dsh-plugin-sleep-not-permitted
临时关闭而不卸载:将配置中 enabled 设为 false,或在插件管理页关闭 sleep-not-permitted 条目。
注意:插件随当前 DSH 进程权限运行,安装前请自行审阅仓库源码与 MIT 许可证;社区目录 SkillHub 为独立站点,与 DeepSeek / 幻方无官方从属关系。
配置要点¶
在 profile 的 cordis.patch.yml 中按 id 覆盖,或编辑插件包内 cordis.patch.yml。节选常用字段:
- id: sleep-not-permitted
name: 'dsh-plugin-sleep-not-permitted'
config:
enabled: true
maxBlockingWaitMs: 30000 # 0 = 拒绝一切前台等待
antiPolling: true
pollRepeatThreshold: 3
pollWindowMs: 120000
interactiveGuard: true
announceInPrompt: true
language: auto # auto | both | zh | en
disabledRules: []
extraRules: []
未知规则 id、空 tools、非法正则等会在挂载期直接报错,不会出现「已安装但未生效」的静默状态。peer 依赖 @deepseek-ai/cordis ^4.0.2 与 @deepseek-ai/dsh-tools;README 写明在 DSH 0.1.5-rc.2 与 0.2.1-rc.3 上验证。
典型验证步骤¶
README 建议用下列方式确认守卫已生效:
- 前台
sleep 5→ 应立即被拒,模型看到Error: …及重试说明。 wait_agent(timeout_ms: 300000)→ 超过默认 30 秒预算,应立即被拒。- 对
sleep 5使用run_in_background: true→ 应立刻得到 jobId,结束后收到完成通知。 announceInPrompt: true时,系统提示中应出现对应规则段。
仓库内测试命令:
node --test test/detect.test.mjs test/plugin.test.mjs
适用场景与边界¶
适合:长期跑 DSH Agent、依赖后台作业与完成通知的工作流;希望统一禁止前台 sleep / 轮询 / 长阻塞 wait,避免会话被无意冻住。
边界(README 已知说明):
- 不猜测「可能很慢」的工作命令(如
npm install),仍走 DSH 原有 timeout 与 promote。 bash script.sh内部 sleep 无法静态检测,只能靠工具 timeout。- 后台作业自身无超时;长任务应自行套
timeout、写 deadline 或结束标记,避免永不通知。 - 中途需要人工决策的任务应先
ask_user_question或走审批,再用非交互参数启动,而不是丢进无 stdin 的后台。
结尾¶
sleep-not-permitted 把「禁止前台等待」从散落的工作区文档收拢到 profile 级插件:提示词引导 + guard 拒绝,并明确要求后台作业或结束本轮。若你在 DSH 里常被 sleep 或长 wait_agent 拖住会话,可以按上文方式安装并做一次前台 / 后台对比验证。
- SkillHub 目录:https://www.skillhub.cn/plugins/JJJACKsong/sleep-not-permitted
- GitHub:https://github.com/JJJACKsong/sleep-not-permitted