前言¶
DeepSeek Harness 在请求超出上下文窗口时会触发压缩(compaction)。压缩不是每次都成功:一旦失败,后续每一条消息都会带着同样的超限请求再发一次,于是同一个错误反复出现,会话只能放弃。
dsh-overflow-fallback 挂在公开的 agent/request-error 瀑布上。当内置策略明确放弃这个失败时,它:
- 确认失败码是
CONTEXT_WINDOW_EXCEEDED(不是网络、限流或鉴权); - 请已加载的压缩后端以
context-overflow触发再压一次; - 只有压缩真的产出了结果,才让这一轮重试一次;
- 每个 agent 最多重试
maxAttempts次,之后老实放弃,不制造无限重试。
它不会伪造成功、不会吞掉错误、不会改动会话日志、不会偷偷截断你的内容。
它是什么¶
dsh-overflow-fallback 是一个 DeepSeek Harness 插件,作者为 WALZX123,分类为「工作流」。插件名称是 dsh-overflow-fallback,在 GitHub 仓库中称为「溢出兜底」。它不做界面、不换压缩引擎,而是在既有策略全部放弃之后先自动再试一次;仍救不回来,就把原会话交接成一个新会话继续。
插件零运行时依赖,核心代码在 lib/ 目录,五个文件不到 700 行,可以完整读一遍。安装后不需要浏览器半区,界面上不会多出入口。
安装¶
从 npm 安装(推荐):
dsh plugin --profile desktop add dsh-overflow-fallback
固定版本:
dsh plugin --profile desktop add dsh-overflow-fallback@0.4.0
或直接从 GitHub:
dsh plugin --profile desktop add github:WALZX123/dsh-overflow-fallback
本地开发安装:
dsh plugin --profile desktop add link:E:\path\to\dsh-overflow-fallback
安装完成后重启一次 DSH。之后改代码不必重启:输入 /reload 即可原地热重载。
配置¶
在 profile 的 cordis.patch.yml 里,对本插件那条装载行加 config:
- insert:
- id: dsh-overflow-fallback
name: 'dsh-overflow-fallback'
config:
enabled: true
maxAttempts: 2
配置字段说明:
| 字段 | 类型 | 默认 | 含义 |
|---|---|---|---|
enabled |
boolean | true |
关掉后插件不注册任何监听 |
maxAttempts |
非负整数 | 2 |
每个 agent 最多尝试几次强制压缩;0 等于停用救援 |
revive |
off / manual / auto |
manual |
救不回来之后怎么办:off 不注册任何动作;manual 只提供 revive_session 工具/服务方法,由人或模型显式触发;auto 在重试用尽后自动开新会话并注入交接包 |
kickoff |
boolean | true |
续命后是否立即跑第一轮:true 让交接包落盘、会话出现在列表(会消耗一次模型调用);false 只排队上下文,会话是空的、列表里看不到 |
recallLimit |
1–200 的整数 | 50 |
recall_original 默认返回多少条事件;单次调用仍可临时指定 limit,上限 200 |
工具与命令¶
插件注册了几个模型工具:
| 工具名 | 作用 |
|---|---|
revive_session |
把当前会话续到新会话(revive 不为 off 时注册) |
recall_original |
按序号或锚点 T3@seq42 回读父会话日志,只读 |
reload_plugins |
用官方 HMR 原地重载改动过的插件 |
/reload |
命令,同上,人从输入框 / 菜单触发 |
recall_original 优先读内存中的父会话;DSH 重启后父会话变冷,会改用 sessionQuery 从磁盘读日志(需要日志文件仍在)。两者都不可用时才报错。
安全边界¶
| 面 | 本插件 |
|---|---|
| 运行时依赖 | 零(package.json 没有 dependencies) |
| 网络 | 插件自身不发起请求;kickoff 会由宿主发一次模型请求(花钱) |
| 文件系统 | 不直接读写;续命创建的新会话由宿主持久化到 $DSH_HOME/sessions |
| 子进程 | 不创建 |
| 会话日志 | 不直接 append;模型可见内容只走 agent.inject() / agent.followup() |
| 权限 | 与宿主进程相同,这是 DSH 插件的固有面;因此本插件刻意把能力压到最小 |
/reload |
作用于整个 profile,会重载所有有变化的插件条目,可能中断进行中的回合 |
完整威胁模型、代价清单与报告方式见 SECURITY.md。
兼容性¶
DSH 里主题、输入框、压缩后端都可能是第三方实现,所以本插件不假设它们存在,也不假设它们的顺序。完整规则见 docs/COMPATIBILITY.md,要点:
| 场景 | 行为 |
|---|---|
| 别的插件已处理这个错误 | next() 优先,原样返回,不抢 |
| 压缩后端被替换 / 缺失 / 正忙 | 调用当时生效的实现;缺失时只记一条警告;忙时放弃本次重试 |
| 子代理、多会话、多端同看 | 按 agent 计数,互不影响 |
| 主题、布局、侧栏 | 插件没有浏览器半区,与主题、布局完全无关 |
| IM(QQ/微信/飞书/钉钉)、远程、headless | 走同一个 agent loop,救援天然生效;但插件按 profile 安装——跑 agent 的那个 profile 里也要装 |
| 卸载 | 监听随 fiber 释放,无残留 |
插件只依赖两处公开面:agent/request-error 事件与 ctx.compaction.compactIfNeeded();任何一处改名都会在装载或调用时明确失败,而不是静默降级。
给插件作者:联动接口¶
本插件注册一个宿主服务 overflowFallback,并在 package.json 的 dshhub.capabilities.provides 里声明:
export const inject = ['overflowFallback']
export function apply(ctx) {
const { markdown } = ctx.overflowFallback.handoffFor(session)
}
服务成员:
| 成员 | 用途 |
|---|---|
isOverflowFailure(failure) |
判断是不是上下文超限 |
handoffFor(session, opts) |
从活的会话生成交接包 |
buildHandoff({ events, ... }) |
从事件数组生成 |
anchor() / parseAnchor() |
生成/解析 T3@seq42 锚点 |
稳定契约(文档大小上限、锚点语法、必备章节、版本策略、失败语义)见 docs/SERVICE.md。服务是只读的:不改会话、不建会话、不发请求。
路线图¶
| 版本 | 内容 | 状态 |
|---|---|---|
| 0.1 | 溢出后强制压缩重试(兜底) | 已完成 |
| 0.2 | 交接包生成:把原会话整理成一份可读的接力文档 | 已完成(lib/handoff.js) |
| 0.3 | 续命:原会话只读保留,新会话带着交接包接着聊;含 revive_session、/reload |
完成,已真机验证 |
| 0.4 | 可回查:recall_original 工具按序号/锚点回读原会话,补齐有损交接的检索面 |
完成,首个对外发布 |
| 0.5 | 可见入口:会话头部右侧的续命按钮 + 预演模式(只返回计划不建会话) | 计划 |
“续命”是真正的目标:聊死的会话不该等于丢掉的工作。兜底重试只是为了少走一步。完整版本路线见 docs/RELEASING.md。
改代码不用重启¶
两个入口,都调用 DSH 官方的 HMR 重载(ctx.hmr.reconcileProfile())——和插件管理器装完插件后做的是同一件事:
- 人用:输入框敲
/reload,回车。命令在宿主侧注册,不占任何布局,只出现在/菜单里,不会和主题或其它插件冲突。 - 模型用:工具
reload_plugins,参数ids可指定条目,留空则重载所有改动过的。
/reload
- 不创建进程、不杀进程、不重启 desktop;
- 只重载”磁盘上的文件变了”的插件条目;
- 客户端插件如需重建 bundle,仍要刷新页面。
适用场景¶
这个插件适合以下场景:
- 在没有 GUI 入口的环境中使用 DSH(如 QQ/微信/飞书网关、
--profile headless、TUI); - 需要在上下文溢出后自动尝试恢复,而不是让会话静默失败;
- 希望保留原有会话内容,通过新会话继续,同时能按序号或锚点回查原文。
安装前建议检查源码与许可证(MIT)。插件以当前 DSH 进程权限运行,能力范围与宿主相同,但自身已尽量压到最小。
总结¶
dsh-overflow-fallback 在 DSH 的上下文溢出场景中提供一个「最后一道救援」:在既定压缩策略放弃之后,先自动再压一次并重试;仍救不回来时,把原会话整理成交接包,在新会话里继续。它不换引擎、不加界面、零依赖,适合在各类 DSH 环境中部署,避免会话因为一次压缩失败而丢失。