前言¶
长会话在 DSH 中容易退化,作者自测约 70% 上下文后会出现“只思考不输出”的情况。DSH 原生的 compaction 是“就地压缩”,用摘要替换原文,历史会被改写。本插件提供另一种方案:当上下文压力达到阈值或会话被压缩次数过多时,开一个新会话,保留一份可审阅的原文交接包,旧会话原样保留。
简介¶
dsh-session-shift 是一个 DSH 插件,所有者为 easerlee。它的核心功能是在上下文压力触达阈值时,将当前工作交接给一个新会话。它不依赖模型总结,而是机械提取会话自身的状态(改动过的文件、用过的工具、最近的消息、停在哪儿),生成交接包落盘。所有操作仅在本地进行,不联网、不外发数据。
安装¶
安装命令根据宿主环境(桌面端或 Web 端)不同而有所区别。
桌面端(profile desktop):
"<DSH 安装目录>\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add dsh-session-shift
注意:需先打开过一次桌面端使 profile 初始化,且执行前完全退出应用(profile 有写锁)。
Web 端(profile web):
dsh plugin --profile web add dsh-session-shift
注意:首次使用时 profile 会自动初始化。
安装后需重启对应端,bundle 列表仅在启动时读取。
配置¶
插件的核心配置位于 profile 的 cordis.patch.yml 中。该文件是 DSH profile 的配置清单,声明本插件作为一个 bundle 挂载,并非修改运行时代码。
配置项示例:
- id: dsh-session-shift
config:
enabled: true
thresholdRatio: 0.6 # 上下文压力到多少比例触发交接
maxCompactions: 2 # 本会话被压缩几次后触发交接(0 = 只看压力)
cooldownMs: 300000 # 同一会话两次交接的最小间隔
handoffDir: .dsh/handoff
recentMessages: 14
maxChars: 24000
renameOldSuffix: " [已交接]"
dryRun: false
stopOldSession: true # 交接完成后是否停掉老会话当前那一轮
用法¶
插件提供了工具调用和 HTTP 接口两种触发方式。
桌面端试跑(不实际建会话):
handoff_now(dryRun: true)
Web 端或命令行手动触发:
curl -X POST http://127.0.0.1:<端口>/api/handoff/run \
-H "content-type: application/json" \
-d '{"reason":"手动换会话"}'
查看状态:
curl http://127.0.0.1:<端口>/api/handoff/status
交接机制¶
自动交接满足以下任一条件且距上次交接超过 cooldownMs 时触发:
1. 上下文压力达到 thresholdRatio。
2. 本会话已被压缩 maxCompactions 次(默认为 2)。
交接发生时按顺序执行三件事:
1. 先将交接包落盘到 .dsh/handoff/。
2. 新建会话,标题格式为 原标题(接 N),N 为旧标题最后编号 + 1。
3. 将旧会话标题加上 [已交接],并根据 stopOldSession 配置决定是否停止老会话当前运行的那一轮。
交接包内容¶
交接包是 Markdown 格式,全部机械提取,不经过模型:
* 改动过的文件:本会话动过的路径(最多 120 条)。
* 用过的工具:按调用次数排序的前 12 个工具。
* 最近几轮消息:用户消息段 + 助手消息段,按预算从新往旧填充。
* 停在哪儿:最后一条助手消息。
已知限制¶
- 兼容性:自动切会话依赖 harness 的
uiWorkspace.openSession接口。如果 harness 较老没有该接口,插件不会报错,也不会自动切换会话,原因会记录在$DSH_HOME/handoff-client-report.json中。 - 旧会话处理:旧会话只改名不归档(有意为之)。
- HTTP 接口:仅作用于该宿主进程里活跃的会话。
许可证¶
MIT