🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

断点续聊 CaiBai-Fish/dsh-continuechat

DeepSeek Harness
CaiBai-Fish24 天前有提交已提供中文文档扫描:未发现敏感能力

一键从中断处继续被停止的对话

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/11 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add CaiBai-Fish/dsh-continuechat
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · chat
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 24 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 恢复中断会话
  • 从断点继续执行

手动恢复中断的 DSH 会话:/continue 和操作行按钮会从停下的地方接着跑。

README

由 DeepSeek 最新模型翻译生成
dsh-continuechat 手动继续被中断的 DSH 对话。 当一轮对话因为手动停止、网络或模型请求失败、或输出 token 上限截断而提前结束时,DSH 只在原地留下一个「已停止」标记。这个插件补上缺的那一步:一条 /continue 命令,以及被中断的那条回答下方操作行里的「继续对话」按钮,让 agent 从中断处接着干活,而不是重新开始。 它解决什么 | 场景 | 不装插件 | 装了这个插件 | | 误触停止 | 只能自己打字「继续」 | 点一下「继续对话」 | | 网络/接口报错中止 | 需要复述上下文再让它接着做 | 插件把失败原因一并交给模型,直接续跑 | | 回答被 token 上限截断 | DSH 提示「发送"继续"」但没有任何入口 | 按钮 / 命令一键续写 | 用法 命令 /continue /continue 剩下的三个文件也一起改掉 命令后面可以跟一句补充指令,它会作为「Additional instruction from the user」附在续接提示词末尾。 命令的执行结果(已请求继续对话(中断原因:手动停止)。)由 DSH 命令面板渲染,不会变成一条模型消息。
展开完整文档(README 剩余 1 节)
dsh-continuechat

手动继续被中断的 DSH 对话。

当一轮对话因为手动停止、网络或模型请求失败、或输出 token 上限截断而提前结束时,DSH 只在原地留下一个「已停止」标记。这个插件补上缺的那一步:一条 /continue 命令,以及被中断的那条回答下方操作行里的「继续对话」按钮,让 agent 从中断处接着干活,而不是重新开始。

它解决什么

| 场景 | 不装插件 | 装了这个插件 |
| 误触停止 | 只能自己打字「继续」 | 点一下「继续对话」 |
| 网络/接口报错中止 | 需要复述上下文再让它接着做 | 插件把失败原因一并交给模型,直接续跑 |
| 回答被 token 上限截断 | DSH 提示「发送"继续"」但没有任何入口 | 按钮 / 命令一键续写 |

用法

命令

/continue
/continue 剩下的三个文件也一起改掉

命令后面可以跟一句补充指令,它会作为「Additional instruction from the user」附在续接提示词末尾。

命令的执行结果(已请求继续对话(中断原因:手动停止)。)由 DSH 命令面板渲染,不会变成一条模型消息。

按钮

被中断的那一轮,最后一条 assistant 消息下方的操作行(和「复制 / 点赞 / 点踩 / 分支」同一行)会出现一个「继续对话」按钮:

- 只在真正中断时出现。正常完成、被拦截(blocked)、fork 结尾(forked)的轮次都不显示,所以它不会出现在正常结束的对话下方。
- 只有承载该轮结束的那条 assistant 消息会显示;同一会话的其他消息返回空,不占位置。
- agent 重新跑起来时自动隐藏。
- 点击后就等于执行了一次 /continue。
- 失败时按钮旁会显示一行错误文本(悬停可看完整信息)。

判定读的是会话的持久事件窗口:取最新一条 turn/end,只有它的 reason 属于可继续集合、且该轮有持久的 assistant 消息时才出现。因此中断但没产生任何 assistant 输出的轮次(例如请求直接失败、进程在流式输出前就断了)没有按钮可放——那种情况用 /continue 命令。

快捷键与命令菜单

输入 / 打开命令菜单,continue(标题「从断点继续被中断的对话」)就在列表中;方向键选中、回车执行即可,无需打开输入框历史。

工作原理

中断检测(host 半侧)

插件订阅会话日志的 session/event,跟踪每一轮的 turn/end:

| reason.kind | 含义 | 视为可继续 |
| aborted | 运行被中止。reason.reason.kind 细分:user 手动停止、parent 被上级操作取消、hook 被钩子取消、disposed 会话销毁 | ✅ |
| error | 模型请求失败(网络、鉴权、服务端错误…) | ✅ |
| max-tokens | 输出被输出 token 上限截断(注意:不是上下文超限) | ✅ |
| interrupted | 宿主进程中断后由崩溃恢复合成的收尾 | ✅ |
| completed | 正常完成 | ❌ |
| blocked | 步骤被 agent/pre-step 拦截,未进入 | ❌ |
| forked | fork 种子在中断处切分支(新会话的开头) | ❌ |

随后任何一条新的 user/message 都会清掉该会话的记录——用户自己接手了,或者插件已经续接过一次。

续接提示词

/continue 不会只发一个「继续」两个字,而是提交一条结构化的 user 消息:

<continue-conversation>
The previous turn ended early: the run was stopped by hand.
Continue the interrupted work in this same session, from exactly where it stopped:
- Do not restart the task, re-summarize, or repeat output and work that is already visible above.
- Treat the current workspace, tool results, and durable session state as authoritative; …
- If a tool call was interrupted, verify its outcome before retrying it, and never blindly retry an operation that may have side effects.
- Finish the remaining work, then verify the result before reporting it.
Failure recorded by the harness: <中断时记录的失败信息> Additional instruction from the user: <命令后面跟的补充指令> </continue-conversation>

针对中断原因分别改写第一句(手动停止 / 请求失败 / 输出截断 / 崩溃恢复),并把 DSH 记录的失败原文附上,让模型知道为什么断的,从而正确决定是接着写、还是先核对工具调用的结果。

回答为什么是独立的一条

点击「继续对话」后,DSH 会新开一轮让模型续写,然后插件把这一轮的触发提示从对话里回收掉——所以你不再看到那段提示,被打断的回答后面紧跟着新写的内容。

回收用的是一条 system/message 替换,而日志把这类事件限定在步骤里:turn/step 必须等于它落盘时打开的那一步,且两个坐标都必须为正(dsh-session-format-v3-to-v4/lib/index.js 的 assertV4SystemMessageFields 与关系重放)。已经结束的轮次没有打开的步骤,替换写不进去。因此回收发生在「模型回答这条提示的那一步」内;如果那一轮没产出回答,则顺延到下一个打开的步骤。

但新内容无法并进原来那一条回答。这是 DSH 会话日志的架构约束,不是实现上的取舍:

- 会话日志是事件溯源的,已提交的 assistant 消息不可修改,只能用 surface replace 遮蔽。
- replace 要求新事件用 sourceEventSeqs 列出每一个被遮蔽的节点(dsh-session/lib/index.js:327),而 assistant/message 被明确禁止携带该字段(同文件 :313,因为它内嵌 provider stream)。两条规则冲突,因此没有任何 assistant 类型的事件能做替换。
- 改用 system/message 之类遮蔽整个区间,会把区间里的 tool/call 与 tool/result 一并遮蔽,破坏模型历史的调用配对,下一轮请求会失败。

provider 侧同样没有 assistant 前缀续写(prefill)能力(dsh-llm-deepseek 只带 anthropic-beta 相关的 beta 标记),模型无法真的「接着上一条 assistant 消息往下写」,必然生成一条新消息。

所以最终形态是:没有多余的「继续」提示,但新回答仍是一条独立的消息。

消息形状

续接消息被手工构造为 { id, role: 'user', content: [{ type: 'text', text }], source: { kind: 'continue-chat' } } 并冻结:

- id 必须自带。Agent.inbox 按 message.id 去重(重复即抛 already pending),且从不补发 id;id 用 node:crypto 的 randomUUID() 生成。
- source.kind 用 continue-chat。Chat 按 source kind 分类 user/message:写 user 会渲染成人类气泡;其他 kind 渲染为注入的上下文节点,而内容为纯文本的上下文节点完全不进入可见节点集。也不要写 'plugin'——那只是格式 v3 的历史形状,v4 读盘时会被拒绝。
- 因此 host 半侧零外部 import(只有 node:crypto),不需要 peerDependencies,也就不受插件版本兼容性拦截的影响。

客户端(浏览器半侧)

浏览器侧只做两件事:

1. 注册 continue-chat 词典(中/英)。
2. 在 conversation.chat.assistant-actions 插槽注册一个动作。这个插槽的 owner prop 是 messageId,渲染进 Chat 的 MessageIconActions,和复制 / 点赞 / 点踩 / 分支是同一个组件——所以按钮天然长在那一行里。

点击后用 ctx.remote.commands.execute(sessionId, '/continue', []) 执行宿主命令,和用户手动敲 /continue 完全同一条路径,因此命令的生命周期记录、结果渲染、日志都一致。

「这条消息是否属于被中断的轮次」由会话自身的持久事件窗口回答:ctx.sessions.binding(sessionId).eventSource 是一个 getSnapshot()/subscribe() 的标准 store,插件用 React.useSyncExternalStore 订阅它,取最新一条 turn/end 的 reason 与该轮最后一条 assistant/message 的 message.id。快照按 revision 记忆化,因此几十条消息共用一次扫描,未命中的行不会重渲染。

安装

在插件目录所在位置执行:

dsh plugin --profile desktop add <插件目录的绝对路径>

例如:

dsh plugin --profile desktop add E:\sourse\plugins\dsh-continuechat

package.json 的 dsh.bundle.patch 指向 cordis.patch.yml,加载器据此往 profile 插入一行 continue-chat;dsh.client.platform = "web" 让宿主把 lib/client.js 作为浏览器 bundle 提供给 Web 客户端。

卸载:

dsh plugin --profile desktop remove dsh-continuechat

它不做什么

- 不自动继续。触发永远来自人:命令、按钮,或者(如果你愿意)自己打字。想要自动续跑请用 goal 工具。
- 不在正常结束的对话下显示按钮。判定完全来自会话日志的 turn/end reason,不看「是不是最后一轮」这类猜测。
- 不把新回答并进上一条消息。架构上做不到,原因见上文;续写始终是一条新的 assistant 消息,插件只回收那条触发提示。
- 不在 agent 运行时插队。运行中执行 /continue 会返回错误提示,请先停止当前轮次。
- 不重写已有历史。续接只是一条新的 user 消息,追加在日志末尾。
- 不在打开的步骤之外回收提示。回收写在「回答该提示的那一步」内;若那一轮没有产出回答,则等到下一个打开的步骤。这是日志唯一接受的位置,也是回收不写在 turn/end 处理里的原因。
- 不重放历史日志。插件只观察进程内新追加的会话事件,所以重启 DSH 后第一次 /continue 会显示「未记录中断原因」,续接提示词退化为通用版本——功能不受影响,只是少了原因细节。
- 不引入任何运行时依赖。host 半侧只 import node:crypto;client 半侧只用平台基座里的 react。没有构建步骤,没有 node_modules。

开发

node --test test/host.test.mjs test/client.test.mjs

- lib/index.js — host 半侧:中断跟踪 + /continue 命令。
- lib/client.js — 浏览器半侧:手写的 window.__ModuleLoader__ bundle(无构建步骤)。
- test/host.test.mjs — 用一个极小的 cordis 假上下文驱动 host 半侧。
- test/client.test.mjs — 用一个极小的 React 假实现驱动浏览器 bundle。
- tools/inspect-session.mjs — 解压某个会话日志(多帧 zstd),列出 /continue 的触发、遮蔽事件与轮次边界,用来核对 surface 记账:node tools/inspect-session.mjs <会话目录>/session.v4.jsonl.zstd。
- tools/verify-retirement-coordinates.mjs — 用 harness 自己的 v4 校验器跑三种候选坐标,证明只有落在打开步骤内的替换才会被接受:node tools/verify-retirement-coordinates.mjs <app 根目录>。

许可

MIT
预览分享卡片长什么样 ↓CaiBai-Fish/dsh-continuechat
分享 · DeepSeek Harness Hub
CaiBai-Fish/dsh-continuechat

一键从中断处继续被停止的对话

这是你的仓库?认领条目

回到顶部