Saltar al contenido principal
G

dsh-turn-sieve

guyou9799/dsh-turn-sieve

Elimina intercambios de poco valor o mensajes individuales de una sesión: selecciónalos en línea en el chat, retíralos de lo que ve el modelo y de la transcripción, y deshaz la operación en un paso.

Instalar

dsh plugin --profile web add github:guyou9799/dsh-turn-sieve

README

dsh-turn-sieve · 回合筛

中文 | English README

不用新开会话,也能把一段对话里不再有价值的问答或单条消息从后续上下文中筛掉,并且可以撤销上一次删除。

DSH 的会话日志是只追加的:一旦聊长了,早期的寒暄、走错方向的尝试、重复的排错过程就会一直占着上下文。dsh-turn-sieve 在会话右上角的工具区加了一个「回合筛」入口,把当前会话按整段问答或单条消息列出来,你可以勾掉不需要的部分,让它们不再进入后续请求。

从 0.6.0 开始,对话里的每一行都能筛除,而且全程不弹任何窗口:

  • 助手回复:鼠标移到回复上,右侧操作条会出现「筛除」;
  • 你自己的发言:鼠标移到这条消息上,气泡左侧会浮现「筛除」;
  • 点一下「筛除」,这一段立刻在原位被选中——背景加深、首尾 18px 圆角、柔和阴影;
  • 同一位置出现 ✓(确认删除)、✕(取消),以及范围切换「整段 / 提问 / 回复 / 仅本条」;
  • 切换范围时高亮会立刻跟着变,确认前就能看清到底会删掉哪几段;
  • 点 ✓ 之后这段内容直接从对话里消失(前端隐藏对应聊天节点),同时不再进入后续上下文;需要时在「回合筛」主面板点一次撤销即可恢复。

✓ 的含义是「确认、选中、正确」,✕ 才是取消——这是 0.5.1 特意修正的交互。

npm

安装

在 DSH Web 的插件页点击「添加插件」,输入:

dsh-turn-sieve

或者使用命令行:

dsh plugin add dsh-turn-sieve

安装后无需重启,打开任意会话即可在右上角看到漏斗图标和「回合筛」。

使用

  1. 打开一个已经聊了多轮的会话。
  2. 点击右上角的 回合筛。面板默认使用液态玻璃外观,标题栏的「液态玻璃」「动效」两个开关可以随时关闭,偏好会保存在本机。
  3. 选择模式:
    • 按整段:一次提问及其后续全部回复、工具调用作为一个整体;
    • 按单条消息:逐条勾选,适合只丢掉某一段冗长回复或某次工具输出。
  4. 在列表上方的搜索框里输入关键词,可以快速缩小范围;勾选后,列表上方会固定显示「将要删除的内容」,它对应会话里的原始提问和回复,方便在确认前再核对一次。
  5. 勾选不再需要的内容(可以多选,也可以全选可移除项)。
  6. 点击「移除所选对话 / 消息」,再点一次确认。
  7. 如果点错了,点击「撤销上一次删除」,再确认一次即可恢复最近一次删除的内容。

直接在对话里筛除(推荐)

不想打开长列表时,直接在对话里操作即可——每一行都可以:

  • 助手回复:鼠标移到回复上,右侧操作条出现「筛除」;
  • 你自己的发言:鼠标移到这条消息上,气泡左侧浮现「筛除」;
  • 不弹出任何窗口:点击后这段对话在原位直接被选中——背景加深、首尾边角变成 18px 圆角并带柔和阴影(不再有那条黑色竖线);
  • 选中的默认范围:从助手回复进入时是「整段问答」,从自己的发言进入时是「提问」;如果某个范围受保护,会自动退到可用的范围;
  • 范围切换有四种,按这段对话的实际构成自动出现:
    • 整段:这次提问 + 智能体的全部回复与工具调用;
    • 提问:只删我在这段里的发言,保留智能体的回复;
    • 回复:只删智能体在这段里的回复与工具调用,保留我的提问;
    • 仅本条:只删当前这一条消息(当「回复」包含多条消息时才出现);
  • 切换范围时,被高亮的内容会立即跟着变,所以确认前就能看清到底会删掉哪几段;
  • 点 ✓ 删除:这段内容会立刻从对话里消失(前端隐藏对应的聊天节点),同时从后续上下文中移除;
  • 点 ✕ 取消选中,一切恢复原样;
  • 删除后仍可在「回合筛」主面板点「撤销上一次删除」,内容会立刻重新出现在原来的位置。
已停止 / 处理失败的回合同样可以删

只要智能体当前没有在运行,最新一段问答就不再被锁住——被手动停止、超时或处理失败的回合可以直接筛除。只有在智能体仍在执行时,最新一段才会显示为「进行中」并禁止删除,避免破坏正在写入的上下文。

回合内的提示卡片也能筛除

「已停止」「本轮运行失败」「已重试模型请求」「已达长度上限」「上下文压缩」「命令」等提示卡片,鼠标移上去后卡片右上角会出现「筛除」,点一下再用 ✓ 确认即可隐藏,✕ 取消。筛除整段问答时,这一轮的提示卡片会跟着一起消失,不会留下误导下一轮的残影。

需要说明的是:这些提示不属于模型上下文——DSH 的 surface 只包含 system/message、developer/message、user/message、assistant/message、tool/result 五类事件,提示卡片只是界面上的状态渲染,不会误导模型,但会干扰阅读。因此隐藏它们是纯前端行为,按会话记录在浏览器本地(localStorage 键 dts-notices:<sessionId>),主面板底部的「恢复提示 (N)」可以一键全部找回。

列表里每一行会显示(并可随时核对):

  • 这段对话或这条消息的开头;
  • 第几轮、包含多少条消息(整段模式);
  • 大约占用多少 tokens;
  • 工具调用数量;
  • 是否属于运行时注入;
  • 受保护的原因(如果有)。

移除后,这些内容不会再进入后续模型上下文;当前上下文会立即变短,下一轮请求即可生效。

两种模式

按整段

  • 从每一条真实用户输入开始新的一段,把这次提问引发的所有助手回复和工具调用都收在同一段里;
  • 系统提示与会话初始上下文受保护;
  • 最新一段只在智能体仍在运行时受保护:已停止、处理失败或已经结束的回合都可以正常删除;
  • 适合清理“整段走错方向”的尝试或大段排错过程。

按单条消息

  • 一条消息一个可选单元;
  • 含 tool-call 的 assistant 消息会和它后续的 tool-result 一起删除,不会留下悬空的工具调用历史;
  • 只保护 surface 节点 0 的 system/developer 上下文,不保护最近一轮——因为这一模式的目的就是删掉某一条不想要的回复;
  • 适合只丢掉一条特别长的工具输出、一次重复回答或一段无关寒暄。

撤销

  • 只保留最近一次删除的撤销记录;
  • 撤销会把原始消息重新追加到会话日志,并解除对应区间的前端隐藏。助手回复、工具调用会在原位恢复;用户提问因为消息 id 会重新生成,会显示在对话末尾,但它能重新进入后续上下文;
  • 撤销记录保存在 Host 进程内存中,DSH 重启后不可用;
  • 助手正在回复时不能撤销,等本轮结束后再试。

安全边界

  • 不会删除原始日志。 插件只向 Session 追加一个空的 system/message 事件,并用 replace surface 操作覆盖选中的区间。原始事件仍完整保留在会话日志里,可用于导出或审计。
  • “从对话中消失”是前端视觉清除。 被筛除的区间由 Host 计算出对应的聊天节点集合(GET /api/dsh-turn-sieve/hidden),客户端把这些节点隐藏;刷新页面、重新加载会话或 DSH 重启后,隐藏状态都会从日志里的删除标记自动重建,不需要额外开关。
  • 系统提示与会话初始上下文受保护。 包含 surface 节点 0 的 system/developer 上下文不会被移除。
  • 整段模式只在运行中保护最新一轮。 单条模式允许删最近的内容,但工具调用与其结果始终成组处理。
  • 助手回复期间不可操作。 当前回合没有结束时,插件会拒绝修改,等本轮结束后再试。
  • 不拆散工具调用。 assistant 的 tool-call 与对应 tool-result 会被当作一个整体,避免产生不完整的工具调用历史。
  • 撤销只有一层。 且撤销记录保存在内存中,Host 重启后会丢失。
  • 提示卡片的隐藏是本机视图状态。 它们本来就不在模型上下文里,隐藏记录按会话保存在浏览器 localStorage,换浏览器或清除站点数据后会重新显示;主面板底部可随时「恢复提示」。
  • 写入失败会被如实报告。 如果 DSH 拒绝了筛除标记(例如会话正在写入),插件会返回自己的错误说明而不是把底层校验器的内部文本抛给你,并且不会留下半删除状态。

和上下文压缩插件的关系

dsh-turn-sieve 不是自动压缩:

  • 压缩插件(如 dsh-compaction-basic、billion-context)在上下文接近上限时自动把旧内容总结成 checkpoint;
  • 回合筛是手动、可挑选的:由你决定哪几段问答或哪几条消息不再重要,然后直接把它们从未来上下文中移除,不生成摘要,也不额外消耗一次总结请求。

两者可以同时安装。

工作原理

DSH 的 Session 有一个「surface」概念:日志保存全部事件,surface 决定哪些事件会投影成模型消息。dsh-turn-sieve 做的事是:

  1. 读取 session.surface.nodes,按 surface 顺序扫描事件:
    • 整段模式:每遇到一条真实用户输入就开启一段新的问答;DSH 在每一步注入的运行时上下文(source.kind === 'runtime-context',以及旧会话里的 Time sampled...、Current runtime context.、<system-reminder>、<hindsight_pages> 等)虽然也以 user/message 记录,但会并入当前问答,不会把一段问答拆散。开头的 system/developer 上下文单独成组并受保护。
    • 单条模式:一条事件一个单元;assistant 消息中的 tool-call 会等待后续匹配的 tool-result 并合并成一个原子单元;此前删除留下的空 system 标记会被隐藏。
  2. 对每个单元生成预览、消息数量、工具调用数和 token 估算。
  3. 用户勾选后,为每个选中区间追加:
session.append('system/message', {
  turn,                    // ≥ 1:format v4 要求 turn 为正数
  step: index + 1,         // ≥ 1:format v4 要求 step 为正数
  message: { id, role: 'system', source: { kind: 'system-prompt' }, content: [] },
}, {
  surfaceOp: { op: 'replace', startSeq, endSeq },
  sourceEventSeqs: shadowedSeqs,
});

空内容的 system message 不会投影成模型消息,因此整段区间从 deriveMessages() 中消失;日志本身没有被修改。

  1. 删除前把被覆盖的原始事件复制到内存的撤销槽;撤销时以 surfaceOp: 'append' 把它们重新追加到末尾,并写入一个 turn-sieve-restored-…-r<startSeq>-<endSeq> 标记。
  2. 每个删除标记的消息 id 里编码了被覆盖的区间(turn-sieve-<stamp>-<index>-r<startSeq>-<endSeq>[-t<turns>][-n<noticeTurns>])。hiddenState(session) 扫描会话事件即可还原“哪些区间被筛掉了”:把区间内每条事件映射成聊天节点 key(13:input-message<消息 id>、14:assistant-step<turn>:<step>、9:tool-call<callId>、16:developer-message<消息 id>),再加上整段模式里完整包含在该区间内的轮次号。客户端拿到 { keys, turns, noticeTurns, ranges } 后隐藏对应 DOM 节点(turns 收起整轮,noticeTurns 只收起这些轮次里的提示卡片),并在轮次容器内所有子节点都被隐藏时一并收起容器;一个 MutationObserver 负责在翻页、重新挂载后重新应用。

注意:替换会让该区间之后的 KV 缓存前缀失效。下一轮请求的输入会明显变小,但首 token 延迟可能略有变化,这是 surface 替换的正常代价。

Agent 工具

插件同时注册了 turn_sieve 工具,助手可以在你明确要求时列出、移除或撤销:

  • action: "list":返回当前会话的单元列表、受保护标记和 token 估算;mode 可选 group / message;
  • action: "prune":传入 mode 和 ranges: [{ startSeq, endSeq }] 执行移除;
  • action: "undo":恢复最近一次删除。

工具和界面共用同一套 Host 逻辑,行为一致。删除操作仍然只作用于当前会话。

外观与动效

  • 液态玻璃:主面板默认采用液态玻璃质感——白色半透明渐变、blur(46px) saturate(200%) brightness(1.14) 的背景模糊、边缘高光、顶部斜向流光,以及背后两团缓慢漂移的柔光。面板内部会强制使用浅色文字与描边变量,因此即使 DSH 处于深色主题,面板依然通透明亮、不会发暗。标题栏的「液态玻璃」开关可以一键切回普通主题底色。
  • 动效:「动效」开关控制两团柔光的漂移和流光扫过;关闭后玻璃质感保留但完全静止。液态玻璃关闭时该开关会自动禁用。
  • 两个开关都是带圆点的胶囊按钮,状态保存在浏览器 localStorage(键名 dts-glass、dts-motion),刷新后仍然生效。
  • 系统设置了 prefers-reduced-motion: reduce 时,动画会自动关闭,只保留静态玻璃质感。
  • 原位选中的加深背景、圆角与阴影基于当前文字颜色(currentColor)混合,浅色和深色主题下都清晰可见,并且没有任何硬边竖条。

限制

  • 只支持当前在 Host 中处于活动状态的会话;已归档或未加载的会话请先打开。
  • 助手回复的「筛除」出现在该回复的操作条里(正在进行的回合结束后才出现);你自己的发言上的「筛除」在鼠标移到该消息时从气泡左侧浮现。
  • “从对话中消失”是前端视觉清除:原始日志仍然保留,导出会话或在别的设备上打开仍会看到完整内容。
  • 隐藏状态按会话推导,多个浏览器标签页各自应用;另一个标签页需要刷新后才会同步隐藏效果。
  • 撤销只有最近一次,且只保存在内存里;重启后无法撤销更早的操作(已隐藏的内容仍会保持隐藏)。
  • token 数来自 tokenMeter 的估算,界面上显示为“约”,用于比较相对大小。
  • 需要 DSH >= 0.2.2-rc.2(Node.js >= 24.9.0)。

更新记录

  • 0.7.2:文档修订——恢复仓库里对「外观与动效」小标题的精简措辞(去掉冗余的「(明亮通透)」),中英文 README 保持一致;运行时行为无变化。
  • 0.7.1:纯文档更新——新增英文 README(README.en.md)与中英各自的 About 详情文档(docs/DETAIL.md、docs/DETAIL.zh.md)和无文字预览插图,英文界面下插件详情页不再回落到中文 README;同时修正说明里过时的 step: 0 示例。
  • 0.7.0:修复致命缺陷——筛除标记此前以 turn/step = 0 写入,而 DSH 的 format v4 写入校验要求两者必须为正数,于是自 0.2.0 起每次筛除都在第一步失败(append_failed),从未真正移除任何内容;现在标记使用 turn ≥ 1、step = index + 1。同时新增回合内提示卡片(已停止 / 本轮运行失败 / 已重试模型请求 / 上下文压缩等)的原位筛除与「恢复提示」,写入失败改为插件自己的错误说明而不再泄漏底层校验器文本,并修掉了每行助手消息都会重复请求 hidden 接口的性能问题。
  • 0.6.0:对话里的每一行都能筛除(自己的发言左侧新增悬浮入口);选中范围新增「提问 / 回复」;已停止与处理失败的回合同样可删;移除选中阴影左侧的黑色竖条;液态玻璃改为明亮通透的浅色玻璃。
  • 0.5.1:✓ 改为确认删除、✕ 取消;筛除后内容直接从对话中消失(可撤销)。
  • 0.5.0:原位选中 + 液态玻璃面板与动效开关。
  • 0.4.0:对话旁「筛除」入口、搜索与「将要删除的内容」预览。

开发

git clone https://github.com/GuYou9799/dsh-turn-sieve.git
cd dsh-turn-sieve
npm test

项目结构:

lib/index.js        Host 插件:HTTP 路由(groups/prune/undo/lookup/hidden)、分组、surface 替换、隐藏区间推导、撤销、Agent 工具
lib/client.js       Web 客户端:会话头部入口、助手回复/自己发言/提示卡片上的原位「筛除」、✓ 确认、聊天节点隐藏、液态玻璃面板、搜索与预览
locale/*.json       插件元数据(各语言的标题、描述与 About 详情文档路径)
docs/               About 页详情文档(中英各一份)与预览插图
cordis.patch.yml    Bundle 插入补丁
test/*.mjs          分组、移除、撤销、lookup、隐藏状态、文档与客户端加载测试
README.md           中文说明
README.en.md        English readme

本地安装:

# 在 DSH 中执行,或使用 GUI 的“安装本地 Bundle”
dsh plugin add /absolute/path/to/dsh-turn-sieve

License

MIT © 2026 Gu You

Plugins relacionados