# dsh-resume-turn DSH 断点续接插件(方案 A2):模型回复因网络中断/超时**半途失败**时,自动把 **已经生成的部分输出**带进下一轮,让模型从断点继续,而不是从零全量重跑。 [English](./README.md) · [仓库](https://github.com/Harris-Logic/dsh-resume-turn) · [问题反馈](https://github.com/Harris-Logic/dsh-resume-turn/issues) · MIT ## 解决的问题 慢速/易断连的供应商(典型:AMD 官方端点 `developer.amd.com.cn` —— 推理慢、 连接频繁断、报 `TIMEOUT` / `TRANSPORT` / `SERVER` / `RATE_LIMIT`)上, DSH 默认的 `dsh-llm-retry` 是"**重跑同一请求**":已流出的内容(包括很长 的思维链)全部作废,多次中断 = 多次从零重跑,最后往往仍失败。 本插件改变这一点:失败瞬间从会话事件日志里捞出**该次尝试已流出的部分 输出**(正文 + 思考过程),向会话注入一条可见的"自动续接"消息(引用部分 输出 + "从中断处继续、不要重复"指令),并以 `{ kind: 'retry' }` 接管恢复 ——下一轮请求从断点继续,而非重头再来。 ## 工作流程 ``` agent/request-error(waterfall) ├─ 用户已取消? → 委托(绝不越过用户停止自动续接) ├─ 失败码不在白名单? → 委托(默认重试处理) ├─ 当前尝试无部分输出? → 委托(没有可续接的内容,全量重跑是正确选择) ├─ 卡在工具调用半途? → 委托(工具参数完整性优先,重启更安全) ├─ 本轮续接预算耗尽(默认3次)? → 委托 └─ 否则 ├─ 从 assistant/chunk 事件(上次尝试边界之后)收集部分正文+思考 ├─ 可取消退避(2s 起步翻倍,上限 30s) ├─ agent.steer(续接消息) # 会话里可见的"自动续接"行;携带部分输出 └─ 返回 { kind: 'retry' } # 重试请求从表层历史重建,天然带上续接消息 ``` ## 安装(一条命令) ```bash # 从 GitHub 安装 npx @deepseek-ai/dsh plugin --profile web add github:Harris-Logic/dsh-resume-turn # 或从本地目录安装 npx @deepseek-ai/dsh plugin --profile web add /绝对/路径/dsh-resume-turn ``` 重启 profile(或 web 宿主)后生效。包内声明了 `dsh.bundle.patch`,安装器会 自动把包名追加进 `dsh.profile.bundles`,其 `cordis.patch.yml` 作为一层自动 生效——**无需手改任何文件**。 > `@deepseek-ai/*`(`schemastery`、`dsh-llm`)由宿主提供:DSH 通过 > `~/.dsh/profiles/node_modules/@deepseek-ai/*` 的符号链接把自身实例暴露给插件, > 因此 `package.json` 里它们是 `peerDependenciesMeta.optional` 的可选 peer, > 既写清了依赖契约,又不会被 pnpm 单独安装出一份重复副本。 ## 配置(均可选) | key | 默认 | 说明 | |---|---|---| | `maxResumesPerTurn` | `3` | 每轮最多自动续接次数;超出交回默认重试 | | `resumeCodes` | `["TIMEOUT","TRANSPORT","SERVER","RATE_LIMIT"]` | 参与续接的失败码 | | `initialDelayMs` | `2000` | 首次续接前等待(随次数翻倍,上限 30s) | | `maxPartialChars` | `12000` | 续接消息引用部分输出的字符上限 | ## 与 dsh-llm-retry 的关系 - `mode: always` 的供应商(A1 已为 amd-egg 配置):`llm-retry` 会先问下游 恢复策略——本插件优先接管(返回 `{kind:'retry'}` 短路全链);本插件放行 时 `llm-retry` 再走自己的退避重试。 - `mode: normal` 的供应商:仅当本插件在 waterfall 中排在 `llm-retry` 之前 才会被征询;否则维持默认的重跑式重试。 ## 已知限制 - 续接消息会把部分输出引用进上下文,衔接处可能有轻微改述("不要重复" 指令已缓解)。 - 续接后若该端点再次失败,尝试次数计入轮预算;超预算后交回默认重试。 - 宿主重启会清空内存中的预算/边界(插件不追加自定义会话事件,存储日志 始终全文可读)。 ## License MIT