DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

elegant01 /

elegant01/dsh-scalpel

Verified

DSH plugin: compare two answers inside one session, and drop chosen turns from every later model request.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@8f128536

dsh-scalpel

DeepSeek Harness 的上下文手术刀。只做两件事:

  1. 同会话对比 —— 同一个会话里前后两次回答,并排看,段落级对齐 + 词级高亮。
  2. 同会话剔除 —— 把指定的若干轮从之后每一次发给模型的请求里摘掉;会话文件、界面、别人的视角都不动。

MIT dsh-plugin


效果

对比面板

这张图是"第 1 轮 vs 第 2 轮"的离线渲染(同一套 lib/compare-core.js),深色两列、段落对齐、改动段词级高亮。插件内的面板用的是同一套布局。

为什么要"剔除"而不是"删除"

会话是 append-only 的事件日志。历史一旦落盘就不可改,任何"删消息"在 DSH 里都只能作用在发给模型的那份副本上:

  • 本插件挂在宿主的 agent/pre-step,在这一轮 messages 组装完成、发出去之前改写它;
  • 规则按 sessionId + 轮号区间 存在 ~/.dsh/scalpel-drop.json,每轮重读,改规则不用重启;
  • 每轮摘了几条、省了多少字符,写进 ~/.dsh/scalpel-audit.jsonl。

代价(是设计选择,不是 bug):

现象 原因
界面和会话记录仍是原样 只改请求副本,真相源不碰
前缀一变,prompt cache 冷一次 上下文前段被改写,缓存键必然变
只能按整轮切,不能拆单条消息 保证 tool_use / tool_result 永远成对,不会 400
永远不剔除当前正在回答的那一轮 否则模型无话可接

安装

发布到 npm 后:

dsh plugin --profile desktop add dsh-scalpel
# 把 dsh.profile.bundles 里加上 "dsh-scalpel",然后完全退出 DSH 再启动

本地开发(仓库就在本机):

# 1) 把仓库链进 profile 的 node_modules
mklink /J "%USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-scalpel" "F:\centos\dsh-scalpel"

# 2) profile 的 package.json:dependencies 加 "dsh-scalpel": "link:../../local-plugins/dsh-scalpel"
#    并把 "dsh-scalpel" 写进 dsh.profile.bundles

# 3) 完全退出 DSH 再启动(bundle 是开机捕获的,刷新页面不生效)

~/.dsh/local-plugins/<name>/ 不会被自动扫描,文件夹存在 ≠ 加载。必须走 profile 的依赖 + bundles 清单。

用法:对比

三个入口,同一套对齐算法:

入口 位置 适合
顶部 对比 tab 会话视图切换栏 长时间并排看
每条回答的 ⚖ 对比 assistant 消息动作行 从某条回答直接开面板
scalpel compare 终端 脚本、分享、code --diff

面板里:左边选一条回答、右边选一条,⇄ 交换,仅看差异 关掉相同段。统计行给的是 总段数 · 相同 · 改动 · 单侧。

命令行:

scalpel sessions --limit 5                 # 最近的会话
scalpel turns latest                        # 这个会话有几轮
scalpel compare latest --a 1 --b 2          # 第 1 轮 vs 第 2 轮
scalpel compare latest --a 1 --b 2 --json   # 结构化输出,给别的工具吃

<session> 可以是会话 id 前缀、文件路径,或 latest。

用法:剔除

scalpel drop latest --from 5 --to 7 --dry   # 先看图什么会被摘掉(只写审计)
scalpel drop latest --from 5 --to 7         # 真摘
scalpel undrop latest                       # 全撤
scalpel rules                               # 当前规则
scalpel audit --limit 20                    # 每轮摘了几条

规则文件长这样:

{
  "version": 1,
  "sessions": {
    "<sessionId>": {
      "dropTurns": [[5, 7]],   // 剔除第 5~7 轮;轮 = 一条用户消息开始的一段
      "dryRun": false          // true 时只写审计,不动 messages
    }
  }
}

CLI 全部命令

scalpel sessions [--limit N]
scalpel turns <session|latest> [--json]
scalpel compare <session|latest> --a N --b M [--json]
scalpel drop <session|latest> --from N [--to M] [--dry]
scalpel undrop <session|latest> [--all]
scalpel rules
scalpel audit [--limit N]
scalpel doctor          # 装了但没生效时先用它
scalpel --version | --help

会话数据来自 ~/.dsh/sessions/<workspace>/session-<uuid>/session.v4.jsonl.zstd(多帧 zstd,按 magic 28 B5 2F FD 切帧解压,Node 22 内置 zstdDecompressSync 直接读,无第三方依赖)。

大会话怎么读的:逐帧解压、逐行解析,读完即弃;只留 12 类事件(turn/start turn/end step/start step/end user/message assistant/message tool/call tool/result session session/title model/selection request/context),工具入参截到 400 字、工具返回只留 callId、流式增量与每轮重复的完整工具表直接丢掉。本机实测:14.7 MB 的会话解出来峰值内存 ~101 MB、1 秒(不瘦身会是几百 MB,一次多读几个就 OOM)。

装了但没生效?

scalpel doctor

一次列出:Node 有没有 zstd、exports["./client"] 在不在、dsh.client 的 platform/immediately 对不对、dsh.bundle.patch 指的文件在不在、宿主半能不能 import、profile 里依赖和 dsh.profile.bundles 两处都写了没、node_modules/dsh-scalpel 的 realpath 是不是这一份、规则文件能不能解析、审计日志可写、探针多久没更新(探针是宿主半第一次跑 pre-step 时写的,没写说明它没被加载)。全部只读,有 fail 时退出码 1。

两个最常见的坑它直接点出来:只加了依赖没加 dsh.profile.bundles(宿主不加载,不报错)和 bundle 是开机捕获的(改完只刷新页面没用,探针时间戳会暴露这一点)。

什么时候别用它

  • 想让模型"以后再也不提 B" —— 剔除只是让它看不见,你自己的会话里 B 还在。要彻底干净,请开新会话 + 交接稿。
  • 想物理删除某段历史 —— 别直接改 session.v4.jsonl.zstd,会破坏 replay。真要删就整会话归档。

文件

文件 作用
lib/index.js 宿主半:pre-step 过滤、规则读写、审计、首轮探针
lib/compare-core.js 纯函数对比核心(分块 / LCS 对齐 / 词级 diff),宿主与浏览器共用
lib/session.js 会话文件解码与轮次提取
client.js 客户端半:对比 tab、⚖ 按钮、对比面板
bin/scalpel.mjs CLI
cordis.patch.yml 挂载入口

开发

无构建步骤:纯 ESM,client.js 是手写 bundle(不走 tsdown/tsc,window.__ModuleLoader__ 包装)。

node --check client.js
node --check bin/scalpel.mjs
node bin/scalpel.mjs rules

Roadmap

v1 之前列的:

  • 自动配对:同一问题问了两遍,自动把两次回答配成一对
  • 话题分段:长会话按话题切开,可整段屏蔽
  • 面板内的 dry-run 预览与一键撤销
  • /compare /drop 两个会话内命令

从 AgentActa 借来的(它是同类日志面板,这两条已经被证明有用):

  • 对比面板的指标行:耗时 / 模型 / token / cache 读取 / 工具次数,每格标"谁大、差多少"。数据都在 assistant/message.data.usage 与 turn/start..turn/end 里
  • 上下文占用与删除报价:request/context.data.contextWindow 给出窗口大小,drop --dry 就能报"省 N tokens ≈ 窗口的 X%",比现在的字符数有意义
  • 单轮导出:把"将被摘掉的轮次"原文 + 解析结果 + 版本指纹导成 JSON,删除前留证据
  • 全文搜索定位:不知道 B 是第几轮时,借 AgentActa 的索引(127.0.0.1:14570/api/search)找,没跑就退回按轮次序号

有意不搬的(都在它的 README 里):历史归档冻结(DSH 的 session 文件本身就是真相源,再存一份是明文重复)、32 家 agent 解析器、慢轮排行与工具失败画像(那是日志分析,不是动上下文;本机已装 AgentActa 当 DSH 插件,重复建设)、SSE 流式双列对比(两边状态一乱就不可信)。子会话拓扑也先不做——本机 39 个会话头里只有 delegationDepth,全是 0,没有父链字段可读。

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 8f128536c4d6

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout