dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
压缩后端,替代默认的 compaction-basic:用可配置的低成本模型池压缩对话内容,按所选模型的上下文窗口切块,并将所有摘要一次归并,支持逐路由冷却与会话模型兜底。
DeepSeek Harness 的上下文压缩插件。
替代默认的 compaction-basic :用指定的低价/免费小模型压缩对话内容,节省成本。
部分模型的上下文窗口较短、装不下完整对话,所以采用分块与归并:切块逐个交给小模型摘要,再把所有摘要一次归并成最终结果。
一次压缩按以下流程进行:
Stage 0 → (选模型 → 切块 → 摘要) × N → 归并 → Checkpoint
cap_i(按块大小占区域总长的比例分配),保证最终归并不会超出上下文限制。cap_i)。mergeMaxContextTokens(归并前最多保留多少上下文,默认128k)控制。已在 DSH desktop 0.2.0-rc.2 上实测通过(CLI 0.1.7-rc.1 亦验证),依赖声明为 >=0.1.7-alpha.2 <0.2.0-0 || >=0.2.0-rc.1 <0.3.0-0。
直接从 GitHub 仓库安装:
dsh plugin --profile <name> add github:bvbhu/dsh-quilt-compact
包声明了 dsh.bundle,安装命令会自动激活随包层并禁用 compaction-basic
(本插件成为 ctx.compaction)。建议用 #<sha> 后缀钉住提交,避免裸仓库
跟随默认分支:
dsh plugin --profile <name> add github:bvbhu/dsh-quilt-compact#<sha>
dsh plugin --profile <name> update dsh-quilt-compact
dsh plugin --profile <name> remove dsh-quilt-compact
之后在 profile 层重新启用 compaction-basic 即恢复默认后端。
两种方式等价:Web UI 的设置页(写入同一份 profile patch),或直接编辑
profile 的 cordis.patch.yml(后层按行生效)。
- id: dsh-quilt-compact
config:
tiers:
- name: primary
models:
- provider: openrouter
model: openrouter/free
maxConcurrent: 1
cooldownHours: 1
cooldownHours 失败后冷却的小时数 (正数,允许小数,如 0.5 = 30 分钟),从失败时刻起算。默认1 小时。
maxConcurrent 默认 1。
归并前最多保留多少上下文用 mergeMaxContextTokens(token 数,默认128k)控制,归并时会在池内逐级下降找上下文足够的模型。
mergeMaxContextTokens: 64000 # 归并前最多保留多少上下文(归并窗口),默认 128000
注意:默认 128k 意味着若主池没有任何 ≥ 128k 的模型,可能会导致归并过程没有模型而失败。
chunkRatio: 0.8 # 分块占用模型可用输入的比例
chunkOverlapRatio: 0.1 # 相邻分块重叠占分块预算的比例
preprocessing:
dedup: true # 合并相邻重复行
purgeErrors: true # 清除终端噪音(ANSI、光标标记、长分隔线等)
astSkeleton: { enabled: false, maxDepth: 2 } # 代码骨架化(按缩进层级保留结构行);默认关闭,需显式开启
logCondense: { mode: balanced, maxLines: 200 } # 超长日志冷凝
可选的质量评估/诊断记录,默认关闭:
runRecord:
enabled: false # 关闭时不产生任何运行记录
maxEntries: 200 # 文件最多保留多少条(超出裁剪到最近 N 条)
snapshotChars: 0 # >0 时每条嵌入一段截断的对话原文(默认 0 = 不存原文)
path: '' # 固定文件位置;留空用 DSH storage 根目录
启用后,每次压缩追加一行 JSON 到
<DSH home>/storages/dsh_quilt_compact_runs.jsonl(非空 $DSH_HOME 优先,否则 ~/.dsh;path 可覆盖)。每条含统计(trigger、regionChars、chunkCount、mergeLevels 等)和 result(最终摘要文本)。
默认不保存对话原文——记录的是"引用"而不是副本:
ref — { sessionId, seqs }:指向会话事件日志里的被压缩区间,需要原文时按 seq 读回(会话是原文唯一合法的存放处)。chunks — 每块模型归属 { chunk, model, lineStart, lineEnd, tokens },回答"哪段是谁处理的",不含文本。cooldowns — 每次进入冷却的报错 { model, job, error, until, hours }:哪个路由、在哪个任务上、因何错误、冷却到何时——排查"某路由为何失败"的第一手证据(聚合尝试计数无法区分真实供应商错误与归属错误)。snapshotChars > 0 才嵌入截断原文副本(隐私 opt-in)。压缩失败不再只留一句固定文案:
dsh-quilt-compact summarize failed (trigger=…): <原因>,原因是扁平化错误链(顶层: 中间: 根因),含整批失败的逐路由尝试摘要(attempts: p1/m1 x1 (last: …); …)。summarize() 之后的失败统一输出 dsh-quilt-compact compaction failed (trigger=…, stage=…): <原因>;跨层传播的同一失败只记一行。failed: true、route: 'error'、error(扁平化原因),与成功同结构;成败比例与失败原因可直接在 JSONL 上统计。mergeWindow、每个路由的 window 与冷却状态,并给出出路(调低 mergeMaxContextTokens 或增加大窗口模型)。/compact — ManualCompactionError 的 message 携带底层原因(会话日志的 compaction/end 事件与本插件的日志都会显示它);自动压缩失败(step 压力、上下文溢出)的 warn 行也携带扁平化原因。宿主的 /compact 命令按错误码输出固定文案并丢弃 error.message;真实原因始终在本插件的 error 级日志(以及 runRecord 开启时的 JSONL)里可查,无需改动宿主导包。
dsh-compaction-basic,可 fallbackToSessionModel: false 关闭)。归并因"池中无足够窗口的健康模型" 而兜底时记录带fallbackReason:no-merge-model 以便与模型故障区分。model pool cannot serve this compaction (…) 标注。默认不记录:默认的持久化状态仅用于记录路由冷却时间,不保存会话消息、提示词或摘要。
开启 runRecord 后:每次压缩(成功的和失败的)写入 JSONL 运行记录——
默认仍不保存对话原文:记录的是 ref(会话 + seq 引用)、每块模型归属和冷却报错,需要原文时按引用从会话读回。只有把 snapshotChars 显式设成正数,记录里才会嵌入一段截断的对话副本(这是保存对话内容的 opt-in)。
0.2.0-rc.2 与 CLI 0.1.7-rc.1 上实际验证过;其他版本未逐一测试。peer 范围写成两段 || 分支(>=0.1.7-alpha.2 <0.2.0-0 || >=0.2.0-rc.1 <0.3.0-0):node-semver 只在该元组上存在带预发布标签的比较符时才放行预发布版本,所以单一的 >=0.1.7-alpha.2 在 npm 的严格语义下排除 0.2.0-rc.2(宿主自身的 peer 检查用 includePrerelease,行为不同,因此从 DSH 安装时不会暴露这个问题)。preset-standard 内的拷贝:通过 Web UI设置页修改时由插件桥接统一写入,无需手工处理;只有直接编辑 cordis.patch.yml 或 preset 重述时才需要注意两份配置的一致性(或重跑生成器),否则两处会漂移。test/bench/ 提供两层验证:
npm test:脚本化 summarizer persona(perfect / leak / forgetful),结果跨机器稳定;回归阈值对照 test/bench/baseline.json(配 tolerance),并断言每次发出的请求都满足 input + maxTokens <= contextWindow。npm run bench -- --real:用真实 ctx.llm 跑同一管线,结果只报告、不设阈值。