DeepSeek Harness 插件

dsh-message-editor

Recall (撤回), edit-and-resend (编辑重发) and regenerate (重新生成) for DeepSeek Harness conversation messages — Web and Desktop(英文原文)

跳到安装方式

来源信息

GitHub 仓库
azmavethy/dsh-message-editor
最近更新
2026年8月20日
分类
记忆
GitHub stars
1
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/azmavethy/dsh-message-editor
插件名:dsh-message-editor
作者:azmavethy

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh.md来源说明 · 只读预览
README 语言

<div align="center">

↩️ dsh-message-editor

DeepSeek Harness 对话消息带来 撤回 · 编辑重发 · 重新生成 —— 同时支持 Web 端桌面客户端 (两者共用同一套 Web 前端)。

![npm version](https://www.npmjs.com/package/dsh-message-editor) ![License: MIT](https://github.com/azmavethy/dsh-message-editor/blob/main/LICENSE) ![DSH plugin](https://github.com/topics/dsh-plugin) ![PRs Welcome](https://github.com/azmavethy/dsh-message-editor/pulls)

简体中文 · English

</div>

DeepSeek Harness 的对话是「只追加(append-only)」的事件日志,本身没有撤销能力。 dsh-message-editor 为对话补上聊天本该有的三个操作 —— 撤回编辑重发重新生成

撤回/编辑后,目标消息会从对话视图和模型上下文中移除——你看到的"删除"正是这个 效果。但底层的持久化日志不会被改写或删除:它始终保持只追加,旧事件原样保留, 插件只是在日志末尾追加一条合法的替换事件(与内置压缩使用的 replace 原语一致)来 回退对话表面,因此日志保留每一次回退的完整审计痕迹。

---

✨ 功能

操作入口效果
↩ 撤回悬停任意助手回复;或用户消息下方的操作行移除整轮对话(该条输入及其对应的输出、工具行一并消失),从模型上下文与对话视图中同步清除,并把输入原文回显到输入框方便立即修改后重发;一条短暂提示标记回退点,你继续输入后自动消失。
✎ 编辑重发用户消息下方的操作行回退并隐藏旧消息及其回复。默认从新对话开始(此前的消息一并隐藏、不再进入上下文),发送修改后的文本让智能体作答;新消息下方有一个折叠的「原提问」对照,点击展开、可配置关闭。
↻ 重新生成悬停任意助手回复回退并隐藏该回复及其后内容,重新发送原提问,让智能体重新作答。

为什么与众不同

  • 🎯 整轮撤回 —— 一键移除输入 它的输出(含工具行),而不只是单条气泡。
  • 🖥️ Web + Desktop 双端 —— 同一插件覆盖 DeepSeek Harness 两种界面。
  • 🔒 删除的是视图与上下文,不是日志 —— 被撤回/编辑的消息从对话视图和模型上下文中

消失,但持久化日志从不被改写或删除;插件只追加合法、带类型的会话事件(与内置压缩 使用的 replace 原语一致),日志保留完整审计痕迹。

  • 🧠 视图 ⇄ 上下文同步 —— 对话视图永远反映智能体真正看到的内容。
  • 30 秒上手 —— 动态插件形式无需重建即可在当前会话试用。

---

🚀 快速开始

> 需要带 dsh CLI 的 DeepSeek Harness。以 profile bundle 方式安装,并自动重建 Web 客户端:

# DSH Desktop(desktop profile)
dsh plugin --profile desktop add dsh-message-editor

# 独立 Web 部署(`dsh web` / web profile)
dsh plugin --profile web add dsh-message-editor

> ⚠️ 安装后需要重启。 运行中的应用仍在内存中保留之前加载的 bundle,请退出并 > 重新打开 DSH Desktop(独立 Web 部署则重启 dsh 进程)后插件才会生效。

重启后,悬停任意助手回复或用户消息,即可使用 ↩ / ✎ / ↻。

---

📦 安装

1. Profile bundle(推荐)

包声明了 dsh.bundle 清单,可通过官方插件路径安装到任意 profile:

dsh plugin --profile <name> add dsh-message-editor

> ⚠️ 安装后需要重启。 安装会写入新文件并重新生成 profile 组合,但运行中的应用 > 不会热加载 bundle —— 请退出并重新打开 DSH Desktop(独立 Web 部署则重启 > dsh 进程)来加载插件。卸载:dsh plugin --profile <name> remove > dsh-message-editor(卸载后同样需要重启)。

同时可在 dsh-market 里一键安装 (安装后同样需要重启)。

2. 手动安装(不依赖 dsh CLI)

用纯文件编辑 + pnpm 装进同一个 profile —— 也就是 dsh plugin add 帮你做的那些步骤:

1. 打开 profile 清单(默认位置:DSH Desktop 为 ~/.dsh/profiles/desktop, 独立 Web 为 ~/.dsh/profiles/web),同时加入依赖 bundle 层条目:

``json { "dependencies": { "dsh-message-editor": "^0.2.0" }, "dsh": { "profile": { "bundles": [ "@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-message-editor" ] } } } ``

(保留 profile 原有条目,只需新增 dsh-message-editor 这两处。)

2. 在 profile 目录里安装:

``sh cd ~/.dsh/profiles/<name> && pnpm install ``

3. 重启 DSH Desktop / dsh 进程(见上文)。

本地开发时,可以把依赖指向本地检出目录而不是注册表: "dsh-message-editor": "file:/路径/to/dsh-message-editor" —— 或者交给 dshdsh plugin --profile <name> add /路径/to/dsh-message-editor

3. npm 包 + 组合文件(经典方式)

npm i dsh-message-editor

在所使用的应用/部署的 cordis.yml 组合文件中加入一行普通插件条目:

- name: 'dsh-message-editor'

Client 半区会依据包内 dsh.client 元数据被自动打包进 Web 客户端(组合变化时会自动 重建客户端模块);Host 半区为浏览器 UI 注册同源 HTTP 路由 /api/plugins/message-editor/*

4. 动态插件(当前会话,免安装、免重建)

包内提供了两个自包含的动态入口:

1. 打开插件编辑界面,用 lib/dynamic-host.js(Host 半区)和 lib/dynamic-client.js(Client 半区)新建插件; 2. 批准并运行 Client 半区; 3. 完成 —— 悬停任意助手回复或用户消息,即可使用 ↩ / ✎ / ↻。

动态 Host 通过 harness.handle 注册同一组操作 (messageEditor.recall / messageEditor.editAndResend / messageEditor.regenerate)。

---

⚙️ 设置 → 通用

设置项默认说明
编辑后显示原提问对照重发消息下方的折叠「原输入」引用,显示最近一次被替换的原文(仅作对照,不会进入模型上下文)。
编辑后从新对话开始编辑后连此前的消息也一并隐藏,让对话看起来像从新消息重新开始(重发前回退整个表面)。

---

🧠 工作原理

 持久化日志(只追加)                     模型上下文与视图
 ┌────────────────────────────────┐     ┌──────────────────┐
 │ ... 目标消息                    │     │  … 目标消息       │
 │     ↓ 阴影区间                  │     │       ↓ 回退      │
 │ [目标 … 最后一个表面节点]        │ ───▶│  (空 replace      │
 │     ↳ 追加一条替换型             │     │   = 上下文截断)   │
 │       assistant/message(空)   │     └──────────────────┘
 │     ↳ 可选「原提问」对照          │     agent.followup(新提示)
 └────────────────────────────────┘     → 下一轮基于回退后的历史重建请求

1. Host 核心lib/host-core.js,零运行时依赖):在会话的活跃表面中定位目标 消息,计算阴影区间 [消息 … 最后一个表面节点],追加一条空内容的替换型 assistant/message —— 空助手消息是合法表面节点,但派生不出任何模型消息, 因此 LLM 上下文直接回退。 2. 编辑 / 重新生成:额外调用 agent.followup(...) 发送(新的)提示文本, 智能体的下一轮请求基于回退后的 session.deriveMessages() 构建。 3. Clientlib/client.js)注册: - 每条用户消息下的 user-actions 对话节点(编辑/撤回行 + 内联编辑器); 撤回后把原文回显到输入框, - recall-marker 节点渲染器:提示行 + 注入 CSS 把被阴影化的消息行从对话流中 隐藏(视图与模型上下文保持同步),并可显示「原提问」对照块, - conversation.chat.assistant-actions 中的 message-editor 入口 (撤回/重新生成), - 设置 → 通用 中的两个偏好开关。

> 这里有两个不同层面:持久化日志(只追加;旧事件从不被改写或删除)与 > 模型可见表面(由追加的替换事件回退)。因此旧事件作为审计痕迹留在记录中—— > 但它们会被同步地从模型上下文和可见对话中清除,界面始终反映智能体真正看到的内容。 > 因为插件只追加合法、带类型的会话事件,持久化、投影与记录保持一致。

---

⚠️ 要求与限制

  • 只有用户消息可以编辑;撤回同时适用于用户与助手消息。工具结果会随区间一并

被阴影化,但不能单独作为撤回目标。

  • 智能体必须空闲:回复流式输出时需先点击 ⏹ 停止,再撤回或编辑;否则 Host

返回 agent-busy

  • 撤回/编辑作用于活跃模型表面:已被压缩或此前已撤回的消息会被拒绝

target-shadowed)。

  • 重新生成只重发原提示的文本部分;携带图片的提示会退化为仅文本重发。

---

🗺️ 路线图

  • [ ] 版本时间线 / 重掷 —— 浏览并跳转到一条消息的历次回退
  • [ ] 分支会话编辑 —— 编辑历史消息并在新分支会话中继续
  • [ ] 支持更多语言(当前:简体中文 / English)

---

🛠️ 开发

# 目录结构
lib/host-core.js       # 传输无关的 Host 逻辑(无 import)
lib/index.js           # 发布版 Host:harness RPC + HTTP 路由
lib/client.js          # Client 源码(import React;传输层可插拔)
lib/client.bundle.js   # 构建产物 —— 自注册 loader entry
                       # (`window.__ModuleLoader__.load`),由 client-modules 提供
lib/dynamic-host.js    # 生成的动态 Host 半区(源自 lib/host-core.js)
lib/dynamic-client.js  # 生成的动态 Client 半区(源自 lib/client.js)
scripts/build-client.mjs      # 打包 lib/client.js → lib/client.bundle.js
scripts/generate-dynamic.mjs  # 从权威源生成两个动态入口
scripts/check-dynamic.mjs     # 语法检查动态入口(函数体形态)
test/                 # vitest 套件:host-core 操作 + 生成产物冒烟测试
.github/workflows/    # CI(语法 + 构建同步 + 测试)与 npm 发布(v* tag)
cordis.patch.yml      # dsh.bundle profile patch 层
pnpm install          # 安装开发依赖(vitest、esbuild)
pnpm check            # 语法检查源码与生成的动态入口
pnpm build            # 重新生成 lib/dynamic-*.js 与 lib/client.bundle.js
pnpm test             # 运行 host-core 单元测试
npm pack --dry-run    # 校验发布文件清单

> ⚠️ 生成文件。 lib/dynamic-host.jslib/dynamic-client.js 与 > lib/client.bundle.js 是由 lib/host-core.jslib/client.js 生成的构建 > 产物 —— 请勿手改。CI 会在构建产物与源码不同步时失败 > (git diff --exit-code),因此提交前记得执行 pnpm build。动态 Client 与 > 发布版共用同一份 client 源码,仅通过 __setMessageEditorWire 切换传输层 > (host.call vs HTTP 路由)。

欢迎提交 PR 与 issue —— 见 [CONTRIBUTING](./CONTRIBUTING.md)(筹备中)与 问题追踪

---

📚 生态

收录于 dsh-plugin topic,可在 dsh-market 一键安装。DeepSeek Harness 插件生态的精选总览见 awesome-dsh-plugin

---

👥 团队

OfferKuai 团队开发——一款 AI 求职助手,使命是 「用户要的是结果,而不是反复的对话」。创始人:Zhaofeng(Yaming)。本插件以开源 形式发布,回馈 DeepSeek Harness 社区。

📄 License

MIT