dsh-tool-result-guard
Verifieddsh-tool-result-guard · v0.1.0 · MIT
Zero-loss tool-result pruning for the DeepSeek Harness (DSH): oversized tool results are spilled to a file first, then pruned with exact elided-span offsets and a recovery locator. A dsh-plugin.
Install
dsh plugin add dsh-tool-result-guard Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Creators
Readme
dsh-tool-result-guard
English | 中文
DeepSeek Harness (DSH) 的零丢失工具结果剪枝插件。 一个 dsh-plugin。
超大的纯文本工具结果会先完整落盘(spill),然后才被替换为有界的首尾预览;位于第 0 位的标记携带精确的被省略区间与 spill 文件定位符。模型永远可以找回中间部分;任何文本都不会在没有持久副本的情况下被丢弃。
[pruned: kept chars [0, 4096) + [28976, 30000) of 30000; the elided middle
[4096, 28976) is NOT lost — full output saved at: /tmp/dsh-spill/.../bash.txt.
Recover any elided span with the read tool (offset/limit), grep, or sed on that file.]
<head:前 4096 字符>
[... middle elided ...]
<tail:最后 1024 字符>
为什么
DSH 内置两套机制:
| 机制 | 触发时机 | 行为 |
|---|---|---|
dsh-spill-policy |
结果 > maxInlineBytes(默认 50000 字节),post-execute 时 |
全文写入 ctx.spillStore,返回有界预览 + 定位符 —— 零丢失 |
dsh-compaction-tool-result-pruner |
文本 > 8192 字符,且仅在 compaction 压力满足时 | 保留头 4096 + [... tool result middle pruned ...] + 尾 1024。原始事件虽留在 append-only 会话日志里供 replay,但模型没有定位符、没有偏移、也没有读日志的工具 —— 中间部分对模型不可恢复 |
缺口:约 8K 字符到 50K 字节之间、存活到 compaction 的结果会被无恢复路径地剪掉。本插件把剪枝提前到 tools/post-execute,先 spill 全文,再在标记里写入精确的省略区间 [head, total-tail) 和定位符。
安装后,内置 pruner 在 surface 上找不到超过 8K 字符的结果,自然空转;其行可留可删,spill-policy 同理(上限永远不会触达)。两者保留无害。
安装
一条命令:
dsh plugin --profile web add dsh-tool-result-guard
重启 DSH 即生效 —— 对该 profile 下的所有预设生效。卸载:dsh plugin --profile web remove dsh-tool-result-guard。
调预算:在 profile 自己的 ~/.dsh/profiles/web/cordis.patch.yml 里按 id 覆盖:
- id: tool-result-guard
config:
thresholdChars: 16384
备选:免 pnpm 的单 preset 安装(只对某一个 agent preset 生效)
npx dsh-tool-result-guard install --preset my-preset --from standard
会把 shipped standard preset 复制到 ~/.dsh/.agent-presets/my-preset/,把 dsh-tool-result-guard.js 放到它的 agent.cordis.yml 旁边并追加插件行;用 my-preset 开新会话即可。已有 user preset 用 --preset <id>(不带 --from)原地打补丁,remove --preset <id> 卸载,--print 只打印片段。等价手动安装 —— 把 index.js 复制到 preset 的 agent.cordis.yml 旁边并追加:
- id: tool-result-guard
name: './dsh-tool-result-guard.js'
配置
未知键在加载时报错。所有预算以 Unicode code point 计(不会拆散代理对)。
| 键 | 默认 | 含义 |
|---|---|---|
thresholdChars |
8192 |
扁平化后的纯文本结果超过该 code point 数时剪枝。 |
headChars |
4096 |
内联保留的头部 code point 数。 |
tailChars |
1024 |
内联保留的尾部 code point 数。 |
excludeTools |
["read"] |
结果永远放行的工具。默认排除 read 以防止 读 spill 文件 → 再被剪 → 再读 循环。可改为如 ["read", "subagent", "memory_search"]。 |
spillDir |
(不设) | 覆盖本地兜底 spill 目录(默认:OS 临时目录下的私有目录)。 |
headChars + tailChars 必须小于 thresholdChars,保证标记永远放得下。
行为准则
- 失败放行(fail-open)。 没有会话属主、spill 后端不可用、写盘失败、或替换结果不满足更小/在预算内 —— 一律保留原始内联结果。剪枝绝不隐藏输出,绝不把成功调用变成错误。
- 先 spill 后剪枝。 中间内容离开模型视野之前,全文已经持久化(优先走部署的
ctx.spillStore,否则写入进程私有的本地目录)。 - 放行规则。 非 accept 决策、value 替换、嵌套复合子调用、被排除工具、含非文本块的结果(图片永不被修改)、以及阈值内的结果,原样返回。
- 可组合。 以 prepend 方式注册
tools/post-executewaterfall 监听器并通过next()委托,工具自身的投影和其他 hook 先执行;被剪的是它们替换后的内容。additionalContexts原样保留。 - 幂等。 替换结果永远在
thresholdChars以内,第二次经过不会再次剪枝。
模型如何找回中间部分
标记给出 spill 文件路径和精确的字符区间。模型用 read(offset/limit)、grep -n 或 sed -n 'X,Yp' 读取该文件即可 —— read 的默认排除保证恢复性读取自身不会被剪。
开发
npm test # node:test,零依赖
许可证
MIT