Idle-time context truncation for a single DeepSeek Harness session. After a configurable number of idle hours the older conversation is dropped without a summary, so one long-lived session cannot leak one task into the next; it ships a per-session toggle, a tab next to the chat, and a /truncate command that IM bridges can drive.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-session-turncate
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:L7X6899/dsh-Session-Turncate
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
This plugin publishes its README in Chinese only.
中文简介:针对单个会话的定时上下文截断插件。可配置「多少小时没有输入之后」,把更早的对话整段丢弃(不生成摘要),避免同一个长期会话(例如手机 IM 机器人桥接的会话)把上一个任务带进下一个任务。
English:Per-session idle-time context truncation for DSH Web. After a configurable number of idle hours the older conversation is dropped (no summary), so one long-lived session (e.g. an IM bridge) cannot leak one task into the next.
- 版本:0.1.2(npm 已发布)
- 包名:
dsh-session-turncate显示名:dsh-Session-Turncate - 宿主:
dsh >= 0.2.1-rc.5(engines.dsh) - 许可:MIT
解决什么问题
一个 Session 可能长期存活(例如手机 IM 机器人一直往同一个会话投递消息),不同任务因此共用一份上下文,互相污染。
本插件给每个会话一个开关:开启后,只要距上一次活动已满 X 小时,下一次开始处理消息时就把更早的整段对话丢弃(不调用模型生成摘要),只留一条分界说明。
这是「截断」,不是「压缩」。被丢弃的内容不会留下摘要,也不会再出现在模型输入里。
界面:会话上方「上下文截断」选项卡
会话区域顶部的功能栏(对话 / 轨迹 / 上下文 / …)新增一项 上下文截断(slot conversation.view,order 40)。面板内容:
| 区域 | 行为 |
|---|---|
| 上下文管理 | 开关。启用后当前会话长时间无输入时会话将自动重置,有效降低 token 消耗。 |
| 自动截断上下文时间 | 数字输入框,单位小时,范围 0–24。输入框带 ▲ / ▼ 按钮(浏览器原生 spinner 也在),方便增减。填 0 表示不按时间自动截断。 |
| 保存 | 写入该会话的开关与小时数。 |
| 立即截断 | 立刻执行一次截断(不受时间限制)。 |
| 状态行 | 上次截断时间与累计次数。 |
面板通过同源 HTTP 接口与宿主通信:POST /session-turncate/api,op 为 status / set / cut。接口只接受 loopback 或同源请求,跨源返回 403。
命令
/truncate on 4 # 开启,并在 4 小时无输入后截断
/truncate on # 只开启,沿用已保存的小时数
/truncate off # 关闭
/truncate now # 立即截断一次
/truncate status # 查看当前会话的状态
中文别名同样可用:/截断 on 6、/cut off。
通过 IM 桥接直接发消息(不经过命令注册表)时,这一行必须以 /、/ 或 ! 开头,否则会被当成普通对话:!截断 on 2 会生效,截断 on 2 不会。
每次开关/截断都会得到一条「回执」消息,让手机端也能看到结果。
触发时机
自动截断在每一步(step)开始时判断,并且只在本轮的第一个 step 执行:
- 本轮已经产生的 surface 节点不会被替换;
- 有未闭合的
compaction/start时直接跳过; - 空闲计时按「上次活动时间」计算,
hours <= 0或开关关闭时不触发。
存储
$DSH_HOME/session-truncate.json(默认 ~/.dsh/session-truncate.json),按 Session id 记录。进程重启后仍然有效。
{
"version": 1,
"sessions": {
"<sessionId>": {
"enabled": true,
"hours": 4,
"keepRecentNodes": 0,
"lastActiveMs": 1762000000000,
"lastCutMs": 1762014400000,
"cutCount": 3
}
}
}
| 字段 | 含义 |
|---|---|
enabled |
会话开关 |
hours |
空闲多少小时后截断(0 = 不按时间自动截断,24 为上限) |
keepRecentNodes |
保留末尾多少个 surface 节点不参与截断(默认 0) |
lastActiveMs |
上次活动时间,空闲计时起点(旧字段 anchorMs 会自动迁移) |
lastCutMs |
上次截断时间 |
cutCount |
累计截断次数 |
手动编辑该文件同样生效(插件每次读盘;解析失败会把坏文件另存为 .corrupt 后重置)。
截断是怎么写进会话的
严格照抄内置压缩后端的事务形状,因此 Chat 里会显示一张「已压缩」折叠卡,历史不会凭空消失:
compaction/start;compaction/summary(固定文案,声明这是按时间策略移除、未生成摘要;provider为session-turncate);- 一条
user/message(source.kind为compact-checkpoint),带surfaceOp: { op: 'replace', startSeq, endSeq },sourceEventSeqs覆盖被替换区间内的每个 surface 节点; compaction/end。
compaction/start|end 的 turn 字段必须存在(无 turn 时写 null),否则会话下次加载会因格式校验失败而报错。
安装
从 GitHub(推荐)
# 把 desktop 换成你实际使用的 profile 名
dsh plugin --profile desktop add github:L7X6899/dsh-Session-Turncate
桌面端也可以走应用内的 设置 → 插件 安装。装完重启 DSH(宿主按 ESM 模块缓存加载插件)。
从 npm
npm i dsh-session-turncate@0.1.2
# 或装进当前 profile
dsh plugin --profile desktop add dsh-session-turncate
包页:https://www.npmjs.com/package/dsh-session-turncate(dist-tag latest = 0.1.2)。
本机开发目录
把目录以 link 方式装进 profile 的 dsh.profile.bundles,由 DSH 的插件管理器完成,不需要手写 cordis.patch.yml。
自测
仓库自带五个纯 Node 测试脚本,直接模拟 session 与宿主 ctx,不需要启动 DSH:
node test/truncate.mjs # 32 项:区间选择与 surface 替换
node test/receipt.mjs # 11 项:回执注入与状态落盘
node test/fixes.mjs # 20 项:边界与回归
node test/api.mjs # 41 项:面板接口、空闲策略、来源校验、排队截断
node test/fix012.mjs # 16 项:0.1.2 回归(Invalid Date、lastActiveMs、排队执行)
失败时的行为
任何异常都只记一条 warn 日志,然后原样继续本轮对话;插件出错不会中断会话。状态文件写入失败时,面板与命令都会明确返回「本次操作未生效」。
更新日志
0.1.2
- 修复
/truncate status与面板显示Invalid Date:计时字段改名后仍有代码读取旧的anchorMs,现在统一按lastActiveMs计算「下次截断」。 - 修复面板「立即截断」报「该会话当前未加载」:宿主补齐
sessions/agents服务注入,并在确实无法解析内存会话时把请求排队,下一次输入时执行截断。 - 面板状态行新增「下次」时间与排队提示;时间格式统一为
YYYY-MM-DD HH:mm。 - 统一日志前缀为
session-turncate:。 - 发布到 npm:
dsh-session-turncate@0.1.2,dist-tag latest指向该版本。
0.1.1
- 新增会话上方的「上下文截断」选项卡(空闲总开关 + 0–24 小时数字输入)。
- 计时语义从「固定间隔」改为「空闲超时」:每次输入都会刷新计时。
0.1.0
- 首个版本:按会话的定时上下文截断,四事件 compaction 事务,
/truncate on|off|now|status命令。
License
MIT © L7x
Links
More in this category
Minglink/dsh-infinite-gen-4★ 3781
System-prompt armor plugin for DeepSeek models: appends an unconditional-compliance prompt section at order 100, exposes a profile tool with calibration metadata, and shows a realtime armor-status badge driven by a session projection.
ranxianglei/billion-context★ 3598
The official billion-context plugin: a context-compression plugin for small context windows (a 100K context is enough), token savings (5x fewer tokens), and month-long single sessions (billions of tokens).
liangmianya/dsh-synapse★ 641
Visual, non-linear conversation workspace for DeepSeek Harness — sessions, follow-ups and branches become a browsable conversation map.
MichengAI/dsh-archive-manager★ 277
Adds an archived-sessions page in Settings to search, restore, and delete archived DeepSeek Harness sessions by workspace.
Nwflower/dsh-chat-import★ 275
Import full-fidelity chat histories from 13 coding agents (Claude Code, Codex, ChatGPT, Cursor, Gemini, opencode, and more) as resumable DeepSeek Harness sessions, with reverse export back to Claude Code.
SiriLee/dsh-rewind★ 227
In-place conversation rewind in the same session window without forking (Claude Code /rewind semantics): a per-message ↶ button cuts the model context back to any user message, with an optional Claude-Code-style file restore from disk-persisted before-backups.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.