为 DeepSeek HarnessDSH打造的确定性、零…
30.7/100
综合分
1
GitHub 星标
225
npm 周下载
—/5
用户评分
数据截至 2026/10/5 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-hypercompactnpm 源 · dsh-hypercompact 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · other
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 30 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-hypercompact @ 0.2.4
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/14 18:55:42
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 3 处,展示前 3 条)
- 读取本地文件index.mjs:99
const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')); - 写入本地文件lib/stats.mjs:46
ready ??= mkdir(target, { recursive: true, mode: 0o700 }); - 写入本地文件lib/stats.mjs:48
await appendFile(join(target, fileName(sessionId)), `${JSON.stringify(line)}\n`, { mode: 0o600 });
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 按字节预算压缩上下文
- 零LLM压缩
- 字节级精确召回
为 DeepSeek Harness 提供确定性、零 LLM、按字节预算的上下文压缩,压缩后的历史可字节级精确召回
README
由 DeepSeek 最新模型翻译生成dsh-hypercompact
为 DeepSeek Harness(DSH)打造的确定性、零 LLM、按字节预算压缩上下文的插件,压缩掉的内容都能按字节精确召回。
- 源代码: github.com/mrbeandev/dsh-hypercompact
- npm 包: npmjs.com/package/dsh-hypercompact
DSH 会话一长就会失败,因为每次请求都要重新上传整段对话。dsh-hypercompact 让这个请求保持小巧:一旦超出字节上限,它就在本地用几毫秒压缩旧历史,不额外调用模型。你输入的内容一字不差地保留,智能体可以用 recall 工具把任何被压缩的工具输出原样恢复出来。
目录: 支持的 DSH 版本 · 安装 ·选择器里没有这个预设? · 确认它是否在工作 ·哪些会话会用到它? · 卸载 ·为什么会有这个插件 · 配置 ·工作原理 · 召回工具 ·环境要求 · 已知限制
支持的 DSH 版本
dsh-hypercompact 0.2.4 适用于 DSH 0.1.5-rc.2 到 0.2.x(不含 0.3.0 及更高版本)。 用 dsh --version 查看你装的是哪个 Harness。
展开完整文档(README 剩余 1 节)
dsh-hypercompact
为 DeepSeek Harness(DSH)打造的确定性、零 LLM、按字节预算压缩上下文的插件,压缩掉的内容都能按字节精确召回。
- 源代码: github.com/mrbeandev/dsh-hypercompact
- npm 包: npmjs.com/package/dsh-hypercompact
DSH 会话一长就会失败,因为每次请求都要重新上传整段对话。dsh-hypercompact 让这个请求保持小巧:一旦超出字节上限,它就在本地用几毫秒压缩旧历史,不额外调用模型。你输入的内容一字不差地保留,智能体可以用 recall 工具把任何被压缩的工具输出原样恢复出来。
目录: 支持的 DSH 版本 · 安装 ·选择器里没有这个预设? · 确认它是否在工作 ·哪些会话会用到它? · 卸载 ·为什么会有这个插件 · 配置 ·工作原理 · 召回工具 ·环境要求 · 已知限制
支持的 DSH 版本
dsh-hypercompact 0.2.4 适用于 DSH 0.1.5-rc.2 到 0.2.x(不含 0.3.0 及更高版本)。 用 dsh --version 查看你装的是哪个 Harness。
| DSH 版本 | 2026-10-05 检查的 npm tag | 用 dsh-hypercompact 0.2.4 验证 | create-preset.mjs 创建的预设 |
| 0.2.1-alpha.1 | alpha | ✅ 已测试 | 预设包,用 dsh plugin add 安装 |
| 0.2.0-rc.2 | latest / next | ✅ 已测试,包括持久化的图片卸载投影 | 预设包,用 dsh plugin add 安装 |
| 0.2.0-rc.1 | — | ✅ 已测试 | 预设包,用 dsh plugin add 安装 |
| 0.1.7-rc.2 | — | ✅ 已测试 | 预设包,用 dsh plugin add 安装 |
| 0.1.5-rc.3 | — | ✅ 已测试 | 文件夹 ~/.dsh/.agent-presets/hypercompact/ |
| 0.1.5-rc.2 | — | ✅ 已测试 | 文件夹 ~/.dsh/.agent-presets/hypercompact/ |
| 其他 0.1.5-rc.2 … 0.2.x 版本 | — | ⚠️ 未验证:通过 API 检查后允许使用,但会给出警告;行为不保证 | 自动检测 |
| 0.1.5-rc.1 及更早 | — | ❌ 不支持:没有压缩 API | — |
| 0.3.0 及更新 | — | ❌ 测试通过前拒绝使用(可覆盖:allowUntestedHarness: true) | — |
我需要哪个版本的 dsh-hypercompact?
| dsh-hypercompact | 版本门禁允许的 Harness 范围 | 变更内容 |
| 0.2.4(推荐) | >=0.1.5-rc.2 <0.3.0;已在上面六个版本上测试 | recall 接受部分模型发来的占位参数(result: 0、range: "" 等) |
| 0.2.3 | >=0.1.5-rc.2 <0.3.0 | create-preset.mjs 修复了会让预设消失的过期预设行 |
| 0.2.2 | >=0.1.5-rc.2 <0.3.0 | 处理 DSH 0.2 的纯内容图片卸载 |
| 0.2.0–0.2.1 | >=0.1.5-rc.2 <0.3.0 | 旧的图片处理方式;要修 DSH 0.2.0-rc.2 的图片卸载问题请升级 |
| 0.1.0 | >=0.1.5-rc.2 <0.2.0 | 在 DSH 0.2 上拒绝加载 |
「拒绝」的意思是:插件在启动时记录一条明确的错误,然后不加载;它不会尝试压缩。允许范围内的各版本,预设安装方式并不相同(见下面第 2 步),光靠 API 检查也无法确认运行时完全兼容。升级 DSH 之后,请看升级 DSH。
安装
安装分三步:添加包、创建使用它的预设、在该预设上启动新会话。只装包没有任何效果。DSH 按预设选择压缩引擎,所以插件只在使用含它的预设的会话里运行。
第 1 步:把包添加到你的 DSH 配置档
dsh plugin --profile web add dsh-hypercompact
改为从 GitHub 或本地检出安装
GitHub
dsh plugin --profile web add github:mrbeandev/dsh-hypercompact
Local checkout (keep the folder in place: the profile links to it)
git clone https://github.com/mrbeandev/dsh-hypercompact.git
dsh plugin --profile web add "link:$PWD/dsh-hypercompact"
第 2 步:创建「Hypercompact」预设
node ~/.dsh/profiles/web/node_modules/dsh-hypercompact/scripts/create-preset.mjs
它会复制 DSH 内置的 standard 预设,只改一行:压缩引擎。你已有的预设不受影响。脚本会检测你的 DSH 版本,按版本做对应的事:
- DSH 0.1.7 和 0.2: 它把一个小预设包写到 ~/.dsh/hypercompact/preset-hypercompact/,并替你装进配置档(它自己会跑 dsh plugin --profile web add)。输出结尾是:
+ dsh-hypercompact-preset link:~/.dsh/hypercompact/preset-hypercompact
- DSH 0.1.5: 它写出预设文件夹 ~/.dsh/.agent-presets/hypercompact/:
created preset "hypercompact" at ~/.dsh/.agent-presets/hypercompact
不确定自己用的是哪个 DSH?运行 dsh --version。
- Windows: node %USERPROFILE%\.dsh\profiles\web\node_modules\dsh-hypercompact\scripts\create-preset.mjs
- 自定义 DSH_HOME: 用那个目录代替 ~/.dsh。
- 本地检出: node /path/to/dsh-hypercompact/scripts/create-preset.mjs
第 3 步:重启 DSH,在该预设上启动新会话
1. 停掉 DSH web,再重新启动(dsh web)。
2. 点击 New session。
3. 在发送第一条消息之前,打开预设选择器,选 Hypercompact (standard)。
想让它对每个新会话都生效,就把它设为默认:
- DSH 0.1.7 和 0.2: 在 Web UI 的预设选择器里,把 Hypercompact (standard) 设为默认预设。
- DSH 0.1.5: 把下面内容加到 ~/.dsh/settings.yaml,然后重启 DSH:
agent-presets:
default: hypercompact
预设没有出现在选择器里
在 DSH 0.1.7 及更高版本中,你配置档自己的 ~/.dsh/profiles/web/cordis.patch.yml 会在所有 bundle 之后生效。如果里面还留着 preset-hypercompact 行——通常是预设被禁用或卸载时留下的 disabled: true,或者旧版脚本留下的内联声明——这一行就会把预设藏起来。
升级到 dsh-hypercompact 0.2.3 或更高版本,再用 --force 跑一次脚本。它会删掉这些过期的行,把原文件保留为 cordis.patch.yml.bak-hypercompact,并打印删掉了什么:
dsh plugin --profile web add dsh-hypercompact@latest
node ~/.dsh/profiles/web/node_modules/dsh-hypercompact/scripts/create-preset.mjs --force
然后重启 DSH。想手动修也行,把那个文件里所有 preset-hypercompact 行删掉(预设 bundle 自己会声明预设)。
确认它是否生效
在会话里输入:
/hypercompact
- 它打印一份状态报告(请求大小、触发值、上次压缩):说明这个会话正在用 dsh-hypercompact。
- 提示命令未知: 说明这个会话用的是别的预设。新建一个会话,在发第一条消息之前选 Hypercompact (standard)。
之后请求超过 5 MB 时,压缩会自动发生。你也可以随时运行 /compact。
哪些会话会用它?
| 会话 | 用 dsh-hypercompact 吗? |
| 新建会话,在发第一条消息之前选了 Hypercompact (standard) | 用 |
| 把 Hypercompact 设为默认预设后,任何新建会话 | 用 |
| 新建会话,用的是别的预设(standard、ptc……) | 不用 |
| 已有会话(已经有消息) | 不用。 DSH 在会话发出第一条消息后就固定了它的预设,所以没法在对话中途切换压缩引擎。 |
把已有对话搬过来: 新建一个 Hypercompact 会话,用 @ 提到旧会话(从列表里选)。DSH 会插入那个会话的一份大小受限的快照,智能体就能接着往下做。
升级 DSH
升级 DSH 之后(比如 0.1.5 → 0.2),做两件事:
1. 更新插件,因为插件版本只接受它认识的 DSH 版本:
dsh plugin --profile web add dsh-hypercompact@latest
2. 重新生成预设。 它是 DSH standard 预设在你创建它那一刻的副本,所以重跑脚本,跟上新版本:
node ~/.dsh/profiles/web/node_modules/dsh-hypercompact/scripts/create-preset.mjs --force
然后重启 DSH。
从 0.1.5 升到 0.1.7 或更高版本时,这一步是必须的:新版 DSH 不再读取 ~/.dsh/.agent-presets/,于是旧预设会从选择器里悄悄消失。
脚本会创建新式预设,并删掉它自己创建的旧文件夹。
脚本选项: --from ptc(复制另一个内置预设)、--id my-preset、 --profile tui(默认 web)、--force(覆盖 / 重新生成)、--print (预览,不写入任何内容)、--no-install(0.1.7+:只写入 bundle,不运行 dsh plugin add)、--remove(删除脚本创建的所有内容)。
卸载
先移除预设。预设里还写着包名,包一旦没了,它就加载不了。
node ~/.dsh/profiles/web/node_modules/dsh-hypercompact/scripts/create-preset.mjs --remove
dsh plugin --profile web remove dsh-hypercompact
--remove 会卸载预设 bundle(0.1.7+),或者删除预设文件夹(0.1.5)。如果你把 Hypercompact 设成了默认预设,换一个默认预设(或者在 0.1.5 上从 settings.yaml 里删掉 agent-presets.default)。已经压缩过的会话仍然可读:它们的检查点是会话日志里普通的压缩检查点。
手动把它加进预设
不想用脚本、想把插件放进自己的预设,就替换预设 compaction 组里的 compaction-basic 行。保留 isolate 块:/compact 和引擎必须共用这个组。
- id: compaction
name: cordis:group
group: true
isolate:
compaction: true
toolResultPruner: true
config:
- id: hypercompact # was: compaction-basic
name: dsh-hypercompact
config:
maxRequestBytes: 5000000
targetRequestBytes: 1500000
- id: command-compact
name: '@deepseek-ai/dsh-command-compact'
- id: tool-result-pruner
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
如果你手动往某个配置档的 cordis.patch.yml 里加过 dsh-hypercompact 行,卸载前先删掉它:一行指向不存在的包,会让配置档启动不了。
为什么会有这个插件
长智能体会话里,每次模型调用都会重新上传整段对话。连接慢或者走代理时,真正失败的是请求体大小,不是 token 数:20 MB 的请求上传要几分钟,还没等模型看到就撞上代理的 100 秒超时。DSH 接着会重试同一个超大请求。
内置引擎(@deepseek-ai/dsh-compaction-basic)在这里帮不上忙:
- 它按模型上下文窗口的一定比例触发,而 1M token 的模型可能永远到不了那个比例,哪怕请求体早就大到传不上去;
- 它靠把整段历史发给 LLM 来总结,而这正是那个已经失败的超大上传。
dsh-hypercompact 按字节衡量下一次请求,在本地毫秒级完成压缩,不调用模型。在真实会话上实测,内联截图占请求体的 50–92 %,剩下的大多是工具流量。插件两个都针对。
概览
- 你写下的内容永远不会被裁掉。 每条人类消息都原样留在检查点里,之后无论压缩多少次都不变。你的约束(「never …」「do not …」「only …」)固定在顶部。同样的保护也覆盖子代理会话里父智能体的任务提示词、/goal 轮次提示词,以及团队消息。
- 旧工具调用各自折叠成一行: 工具名、关键参数、编辑操作的 +N/−M lines 摘要,以及指向原文的指针。连续的只读调用(read ×7: a.js b.js …)合并成一行。
- 旧工具结果折叠为状态、大小、一小段头尾摘录,以及一个指针。失败的结果保留更长的摘录。
- 工作状态。 一个区块列出最近编辑的文件、最近执行的命令,以及未解决的错误。
- 图片。 较早的行内图片变成文字标签,附上助手当时对它们的说明。
- 日常清理。 在目标与触发点之间,做一次轻量处理,就地裁剪旧工具结果,而不是重写历史。
- 召回。 模型拿到 recall,可以从只追加的会话日志里还原任意原文,逐字节精确(或者只还原大日志里匹配的那几行),另外还有 recall_search。你拿到的是 /recall 和 /hypercompact。
- 即插即用。 它实现公开的 ctx.compaction 契约,所以 /compact、token 计量器和上下文图表都照常工作。不需要客户端 bundle,不需要设置界面,也不用给 harness 内部打补丁。
实测结果
真实会话,用 npm run measure 离线测量(见开发),走 pi-ai 自己的 OpenAI-completions 序列化器,默认配置。不发起任何 LLM 调用。
| 会话 | 请求前 | 请求后 | 替换数 | 检查点 | 降级 | 逐字保留的用户消息 | 耗时 |
| A(图片 + 工具) | 19.51 MB | 1.08 MB | 2302 | 503 KB | 1 | 31 / 31 | 149 ms |
| B(图片) | 12.37 MB | 0.80 MB | 632 | 221 KB | 0 | 21 / 21 | 96 ms |
| C(图片 + 工具) | 11.42 MB | 1.62 MB | 1337 | 278 KB | 1 | 27 / 27 | 123 ms |
| D(图片) | 10.99 MB | 0.86 MB | 483 | 146 KB | 0 | 8 / 8 | 55 ms |
| E(约 800k token 会话) | 6.40 MB | 1.66 MB | 683 | 222 KB | 0 | 12 / 12 | 86 ms |
| F(混合) | 3.01 MB | 1.09 MB | 581 | 195 KB | 0 | 2 / 2 | 67 ms |
| G(纯文本) | 1.11 MB | 0.59 MB | 809 | 229 KB | 0 | 8 / 8 | 68 ms |
降级为 0 表示只丢掉了推理内容;为 1 表示丢掉了工具结果摘录(调用行和指针保留)。任何会话都没有条目被省略。每个压缩后的请求都是 0 个孤立工具结果、0 个未应答的工具调用,并且 recall 返回的抽样工具结果与日志逐字节一致。
配置
所有键都是可选的。未知键在挂载时会被拒绝,所以拼错会直接报错,而不是悄悄用默认值。
| 键 | 默认值 | 含义 |
| maxRequestBytes | 5000000 | 估算的下一个请求体达到这么多字节时触发压缩。 |
| targetRequestBytes | 1500000 | 压缩到这个大小左右。必须低于 maxRequestBytes。两者之间的差距就是迟滞:每次压缩都会造成一次 prompt-cache miss,所以要大步压缩。 |
| housekeepingRatio | 0.5 | 从 target 到 trigger 之间走到这个比例时开始 housekeeping(默认:3.25 MB 处)。Housekeeping 会就地卸载较旧的图片、裁剪旧工具结果;不生成 checkpoint。0 = 关闭。 |
| housekeepingExcerpt | { head: 2000, tail: 1000 } | 被裁剪的旧工具结果保留的字符数。 |
| maxTokens | 0 | 估算 token 数达到这个值时也压缩(0 = 关闭)。 |
| contextRatio | 0.85 | 达到路由模型 contextWindow 的这个比例时也压缩(0 = 关闭)。两个 token 触发条件取先到者。 |
| retainTurns | 2 | 最新的完整轮次永不压缩。 |
| retainBytes | 400000 | 最新的请求字节永不压缩。 |
| allowIntraTurn | true | 当一个很长的自主轮次占住了字节数时,压缩它较旧的工具流量,保留该轮次的人类消息和最新的 retainBytes。 |
| maxCheckpointBytes / minCheckpointBytes | 600000 / 300000 | checkpoint 的上下界。它的预算是保留轮次之后 target 下实际空出的空间(扣除即将卸载的图片),并夹在这些边界内。 |
| pinnedBytes | 30000 | pinned 块的上限。按顺序裁剪:消息索引(裁到最新 40 行 + 摘要)、文件列表,然后是最旧的约束。 |
| userTextChars | 20000 | 单次病态人类粘贴的硬上限:超过它,保留头 + 尾,并附一个召回指针。预算裁剪过程永不切人类文本。 |
| assistantTextChars | 1500 | checkpoint 中助手文本的长度(头 + 尾);降级裁剪不会低于 1000。 |
| toolResultExcerpt | { head: 200, tail: 100 } | 每个被压缩的成功工具结果的摘录。 |
| toolErrorExcerpt | { head: 600, tail: 400 } | 每个失败工具结果的摘录(预算裁剪永不丢弃)。 |
| groupTools | [read, read_image, grep, glob, ls, web_search, web_fetch, recall, recall_search] | 对其中某个工具的连续成功调用折叠成一行。[] = 关闭。 |
| keyArgChars | 160 | 工具调用行上显示的单个参数最大字符数。 |
| largeArgBytes | 2000 | 参数值大于此值时显示为 <N KB>。 |
| keyArgTools | null | null = 为每个工具显示关键参数;或填工具名列表。其他工具只显示参数大小。 |
| keepRecentImages | 2 | 保留最新的内联图片;请求超过 target 时,较旧的图片变成带说明的标签。 |
| maxKeptImageBytes | 2000000 | 保留图片的字节上限(base64),与数量无关。 |
| recoverOnTimeout | true | 请求因超时/传输失败、且请求体超过 target 时,压缩并重试一次。上下文溢出和 HTTP 413 失败总是会恢复。 |
| maxRecoveryRetries | 1 | 每个智能体的恢复压缩次数,直到它下次进入空闲。 |
| dryRun | false | 只记录会压缩什么,不写入任何内容。 |
| auto | true | 自动触发。设为 false 时,只有 /compact 会压缩。 |
| tools | true | 注册 recall 和 recall_search 工具。 |
| commands | true | 注册 /recall 和 /hypercompact 命令。 |
| recallToolName / searchToolName | recall / recall_search | 工具名,以防别的插件已经用了这些名字。 |
| maxRecallChars | 60000 | 一次 recall 回答的分页大小(更长的输出用 offset 继续)。 |
| maxSearchHits | 30 | 一次搜索返回的最大条目数。 |
| statsLog / statsDir | true / null | 每次压缩后向 <statsDir>/<session>.jsonl 追加一条不含内容的 JSON 记录(默认 ~/.dsh/hypercompact/)。 |
| modelPolicies | [] | 按路由覆盖:[{ provider, model, maxRequestBytes?, targetRequestBytes?, maxTokens?, contextRatio?, retainTurns?, retainBytes?, maxCheckpointBytes?, housekeepingRatio? }]。 |
| harnessEntry | 正在运行的 dsh | dsh 命令行入口的路径,用于无法从 process.argv[1] 找到它的情况。 |
| allowUntestedHarness | false | 在受支持范围之外的 DSH 版本上加载,或在 API 契约检查失败的版本上加载。 |
为什么是这些默认值
- 5 MB 触发。 上行链路慢时(100–250 KB/s),5 MB 大约要传 20–50 s,即使按最慢算,也在常见的 100 s 代理/CDN 超时之内。
- 1.5 MB 目标。 压缩后每个请求约 6–15 s,距离下次压缩还有 3.5 MB 的增长空间(每次压缩都是一次缓存未命中)。
- retainTurns: 2、retainBytes: 400000。 当前轮和上一轮原样保留,智能体不会丢掉正在做的工作。
- contextRatio: 0.85。 给小窗口模型留的 token 安全网,这类模型的会话一直没到字节触发线。
- keepRecentImages: 2。 智能体当前正在看的截图会保留,更早的截图不保留——在实测会话里,它们是开销的大头。
- minCheckpointBytes: 300000。 实测:下限更小时,保留尾部以图片为主的会话只拿到很小的预算,结果省略了数百条条目;设为 300 KB 后,每个实测会话编译时的降级都 ≤ 1,没有条目被省略,同时仍接近 1.5 MB 目标。
在快速连接上、用大窗口模型时,这两个字节值都可以调高(比如 20 MB → 6 MB);token 触发仍会保护上下文窗口。
按模型配置的策略。 默认不带任何策略,因为服务商和模型 ID 因部署而异;provider 和 model 必须与你的路由完全匹配:
modelPolicies:
a route behind a slow proxy: keep every request under ~30 s at ~100 KB/s
- { provider: my-gateway, model: my-model, maxRequestBytes: 3000000, targetRequestBytes: 1000000 }
a 128K-window model: fire the token trigger early
- { provider: deepseek, model: deepseek-chat, contextRatio: 0.7 }
工作原理
触发。 每个模型步骤(agent/pre-step)之前,引擎会估算下一次请求体:每条表层消息序列化为 JSON,内联图片转成 base64,再加上工具 schema 和固定信封。每条消息的大小按日志 seq 缓存,日志增量折叠,所以一步的开销是 O(新增事件),而不是重新扫描整个会话。估算值达到 maxRequestBytes,或者 token 触发器触发时,就执行压缩。
选择。 它替换表层中最旧的一段。这一段永远不包含系统提示词,永远不会从助手工具调用和它的结果之间切开,优先选择轮次边界,并且永远不碰最新的 retainTurns 轮或 retainBytes 字节。压缩量足够让结果落在 targetRequestBytes 附近。
检查点。 这一段会编译成一条 user 消息,包含三部分:
1. 固定项:每条指令消息一行(seq + 首行),其中的每条约束语句原样保留,以及改动过的文件及其最后一次写入的 seq。后续每次压缩都会继承并合并。超过 pinnedBytes 时,先裁剪索引(保留最新 40 行,外加一行「N older user messages: seq a–b」),再裁剪文件列表,约束最后裁。
2. 历史:这一段按顺序排列。指令消息原样出现在 [user seq N] 和 [/user seq N] 之间(或 [agent-message seq N]、[goal seq N]、[team-message seq N])。助手文本保留头 + 尾。每次工具调用一行,带上结果的 status、大小和摘录;连续的只读调用合并成一行。Harness 注入的上下文(agent instructions、subagent reports)会缩短。推理过程丢弃。
3. 工作状态:最后编辑的文件、最后执行的命令及其状态、后面没有成功的错误,以及最后一次人类请求。
如果检查点超出预算,编译器按固定几轮降级:先丢弃成功摘录,再缩短助手文本(不低于 1000 字符)和上下文,然后把最旧的未受保护条目(工具行、助手文本、上下文)折叠成 [N entries elided, seq A–B] 行。人类文本、固定项、失败调用摘录,以及模型最近回忆过的条目,永远不会被折叠。如果只靠它们就超出预算,那就超出预算(记录日志,并写入 stats),而不是丢掉用户说过的话。这一段里更早的检查点会重新解析,而不是直接复制:它的人类块保持受保护,seq 不变,固定项合并,工具行变为可折叠,所以反复压缩始终有界。
编译后的工具行长这样:
• edit file_path="src/net/retry.ts" old_string="const timeout = 30_000" new_string=<3.2 KB> [+84/−1 lines] (seq 1822 → result 1824 ok 23 B)
"Edited src/net/retry.ts"
提交。 与内置引擎相同的持久事务: compaction/start → compaction/summary → user/message(表层替换) → compaction/end,中间不 await。摘要事件带有标准字段(shadowedSeqs、shadowedTokenCount、……),/compact 和 dsh-context 会读取这些字段。原始事件仍留在日志里。如果请求仍高于目标,保留的工具结果中较旧的图片会通过 harness 的纯内容工具结果重写替换(内置 pruner 用的就是这个机制),每张都按 compaction/prune 做影子计价。
内务整理。 在 targetRequestBytes 和 maxRequestBytes 之间(从 housekeepingRatio 开始),每一步先卸载较旧的图片,再把保留轮次之外的旧工具结果裁剪到 housekeepingExcerpt,直到请求回到目标附近。这些都是纯内容重写(与图片卸载同一机制)。不替换任何 span,也不写检查点,所以请求保持平坦,完整压缩及其缓存未命中就更少见。
单个长轮次。 如果保留内容占了大头(一个自主轮次里有数百次工具调用),压缩较旧历史也到不了目标。引擎这时会压缩当前轮次内部较旧的工具流量,保留该轮次的人类消息和最新的 retainBytes,切在平衡的工具边界上(allowIntraTurn)。
感知召回内容的保留。 模型用 recall 取回过的条目会在下一次压缩时钉住:它们的行保持完整细节,绝不省略。
恢复。 遇到上下文溢出、HTTP 413,或者(如果启用)超时/传输错误且响应体很大时,它会压缩,并让智能体循环把请求重试一次。
失败放行。 自动路径里任何错误都只记日志,轮次照常继续。compaction/start 之后的失败会用 compaction/end 和错误关闭括号,和内置引擎完全一样。
协议安全
- 每次提交前,都用 dsh-compaction 自带的 toolPairingBalancedBefore/After 检查工具配对。
- 签名或原生推理重放(replayState、thinking 签名、redacted 块)挂在 assistant 消息上。每条保留的消息都逐字节保留,压缩掉的 span 整体替换为纯文本 user 消息,所以绝不会发出部分重放状态。dsh-short-tool-ids 要求的也是这一点。
- 检查点带有当前 DSH 自己的压缩来源标记(由 dsh-compaction 的 compactCheckpointSource 生成),所有消费方都能识别。来自任一 DSH 版本、或来自 compaction-basic 的早期检查点,在向前携带时都能识别。
- 工具结果通过一个适配器读取和重写,同时覆盖两种 DSH 消息格式(0.1.5 的包装 tool-result 块;0.1.7 和 0.2 的 tool-role 消息)。
- 在 DSH 0.2 中,持久化的 image/offload 事件可以标记图片已省略,而不替换其表面节点。当消息内容代际变化时,Hypercompact 会使其字节缓存失效,把已卸载的图片计价为保守文本占位符,而不是 base64,并且在后续工具结果重写时保留省略内容。
召回工具
每个检查点都会告诉模型如何使用这些工具,以及何时必须使用: 在编辑文件、执行需求,或回答关于早前指令的问题之前——如果该指令内容被截断、省略,或只剩指针——先调用 recall;绝不要猜测被截断的内容。
recall({ seq: 1234 }) 一条日志条目,逐字返回
recall({ result: 1234 }) 在 seq 1234(或在此应答)的工具调用原始输出
recall({ result: 1234, grep: "ECONN", context: 3 }) 大型输出中仅匹配的行(带行号)
recall({ result: 1234, head: 2000, tail: 2000 }) 仅首尾两端
recall({ range: "120-140" }) 一段范围(最多 200 个 seq)
recall({ seq: 1234, offset: 60000 }) 长条目的下一页
recall_search({ query: "ECONNRESET" }) 最新优先,带 seq 指针
recall_search({ query: "csv", kind: "user" }) 仅人类写的内容
recall_search({ query: "fail", kind: "error", since: 5000 }) seq 5000 之后失败的工具结果
recall_search({ query: "fetch\\(.*timeout", regex: true })
设置 seq、result 或 range 其中之一。有些模型会把每个参数都填上,而不是省略未使用的参数({ seq: 1234, result: 0, range: "", grep: "", head: 0 });recall 会把 null、""、负数,以及不可能有意义的 0(result、head、tail、offset)视为未设置。如果设置了多个真实选择器,它会依次尝试 result、seq、range,某个找不到内容时回退到下一个,并在输出顶部说明用了哪一个。recall_search 会忽略 kind、since、until 中同样的占位符。
kind 取值为 user、assistant、tool、result、error、checkpoint、 context 之一。召回读取的是日志,不是实时上下文,所以它也能找到被早前压缩、裁剪或图片卸载遮蔽的内容。对于被裁剪或卸载的结果,它会沿替换链回溯到原始内容。
命令
| 命令 | 显示 |
| /recall 1234、/recall 120-140、/recall result 1234 | 原始条目,在对话记录中,供人类查看。 |
| /hypercompact | 当前请求大小和内联图片、触发条件,以及最近一次压缩或整理过程(跨度、前后字节数、降级、省略条目数、保留的用户消息)。 |
命令注册到挂载预设自己的命令层,所以多个使用 dsh-hypercompact 的预设可以共存。如果某个名称已被占用(例如另一个插件的 /recall),该命令会被跳过并给出警告;引擎和工具从不依赖它。
统计记录
开启 statsLog(默认开启)时,每次压缩和整理过程都会向 ~/.dsh/hypercompact/<session-id>.jsonl 追加一行 JSON:跨度 seq、字节数和 token 前后对比、检查点大小与预算、降级情况、被省略的条目、保留的用户消息 seq,以及任何超出硬上限的 seq、被卸载的图片、被裁剪的结果和耗时。记录里只有数字和 seq,绝不含消息内容。
想回答「为什么它忘了 X」,靠的就是这些记录。
要求
- DeepSeek Harness 0.1.5-rc.2 起,到 0.3.0(不含)为止。已测试的版本见 支持的 DSH 版本,以及
what happens outside the range.
- Node.js ^22.19.0 or >=24.0.0 (whatever your DSH runs on).
- Any profile with an agent-preset roster (the web profile). The headless
profile has no preset roster; see Add it to a preset by hand.
The plugin has no runtime dependencies. At mount time it loads
@deepseek-ai/dsh-compaction, dsh-llm and dsh-tools from the running DSH,
never from a second copy, so the engine subclasses the host's own
CompactionEngine.
Development
npm test # both tool-result formats; real-harness tests run when dsh is installed
npm run verify # tests + release gate (packed files, forbidden mechanisms, syntax)
npm run measure -- ~/.dsh/sessions/<project>/<session>/session.v3.jsonl.zstd
npm run measure loads a session log into a real Session from your DSH install,
serializes it through pi-ai's OpenAI-completions converter, and prints the
request body breakdown (messages by role, tool schemas, inline images). It
then runs one compaction on an in-memory copy with a real TokenMeter and
reports bytes and tokens before/after, checkpoint size vs budget, degradation,
user messages kept verbatim, tool pairing, and a recall byte-equality check.
Pass --config '{"minCheckpointBytes":150000}' to try other settings. The
session file is only read, and message content is never printed.
Set DSH_ENTRY=/path/to/@deepseek-ai/dsh/lib/bin.js to test against a DSH other
than the one on PATH.
| File | Role |
| index.mjs | Plugin entry: version policy, runtime loading, engine, tools and commands |
| lib/engine.mjs | ctx.compaction implementation: triggers, transaction, recovery, housekeeping, image offload, stats |
| lib/compiler.mjs | Deterministic checkpoint compiler: protected instructions, pinned and state blocks, budget passes |
| lib/select.mjs | Retention, tool-pairing, turn-boundary and intra-turn range selection; checkpoint budget |
| lib/messages.mjs | Message-shape adapter for DSH 0.1.5 and 0.1.7 / 0.2 |
| lib/surface.mjs | Incremental per-session surface index and byte cache |
| lib/bytes.mjs | Request-body byte estimation |
| lib/images.mjs | Image offload planning and captions |
| lib/housekeeping.mjs | In-place trimming of old tool results |
| lib/pins.mjs | Recall-aware retention |
| lib/stats.mjs | Content-free per-compaction records |
| lib/recall.mjs, lib/tools.mjs | Recall/search over the log, their tool definitions, and the commands |
| lib/config.mjs | Config validation |
| scripts/create-preset.mjs | Create, regenerate or remove the preset (folder preset on 0.1.5, preset bundle on 0.1.7+) |
| scripts/measure-session.mjs | Offline wire-body measurement and dry run |
| scripts/check-release.mjs | Release gate |
Publishing
Maintainers publish manually from a clean main branch:
npm run verify
npm publish --dry-run --json
npm whoami
npm publish
prepublishOnly runs the tests and the release gate. The package publishes
publicly because package.json sets publishConfig.access to public. A dry
run does not authenticate or publish. See RELEASE.md for the
full checklist.
Known limits
- The byte estimate prices the provider-neutral request, not the adapter's exact
wire JSON. Measured against pi-ai's real serializer it always errs high:
+2–11 % on multi-MB bodies, up to +28 % on small text-only ones. The trigger
therefore fires somewhat early, never late.
- The checkpoint is extractive, not a summary. Reasoning is dropped, so a
decision made only in reasoning is not carried. The agent can recall it.
An optional LLM summary is deliberately not included: it would reintroduce
the large upload this plugin exists to avoid. If ever added, it must run on
the compiled checkpoint (not the raw span), append only, and fail open.
- Human text is protected even when that means exceeding the checkpoint
budget. A session with megabytes of pasted text keeps it (each paste is
capped at userTextChars, head + tail); /hypercompact and the stats record
show the overshoot.
- The token figure logged right after a compaction is stale for one step: the
token meter anchors on the provider's last reported usage and subtracts the
shadowed span at its heuristic price (images priced at vision cost by the
provider are under-subtracted). It re-anchors on the next response. The byte
figure is the reliable one.
- Protected instruction kinds are user, agent-message, goal and
team-message. Other user-role context (plugin, skill-invocation,
subagent-settled, session-reference, agent instructions) is trimmable.
- Constraint detection is a keyword match ("never", "do not", "must", "only",
…). It over-collects rather than misses, and the full message is verbatim in the history anyway.
- Each compaction changes the prompt prefix and costs one cache miss. The
default 5 MB → 1.5 MB hysteresis and housekeeping keep that rare. Housekeeping
rewrites also change the prefix, but only from the rewritten result onward,
and only once per result.
- Images are offloaded only from tool results. Images attached to user messages
are kept until their turn is compacted.
- Intra-turn compaction keeps the current turn's human message and the newest
retainBytes. If those alone exceed the target, the request stays above it.
Credits
The compiler and recall design are informed by the MIT-licensed
dsh-compaction-instant and
VCC. No code is copied from either.
License
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
mrbeandev/dsh-hypercompact
为 DeepSeek HarnessDSH打造的确定性、零…
相关插件 · 其他
模型破甲清洗HunYiSage/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,993已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,269已汉化DSH
70.8
这是你的仓库?认领条目