DSH Hub / 插件 / @wasd258/dsh-context-surgery WASD258-jpg/dsh-context-surgery ↗ ★ 0
@wasd258/dsh-context-surgery Surgical rewriting of the model-visible conversation history of a DSH session (surface replacement); edit reply and reasoning chain separately. 上下文手术刀:强制改写会话的模型可见历史,回复与思考链分开编辑。
包名 @wasd258/dsh-context-surgery
版本 0.1.2
许可证 NOASSERTION
最近更新 2026年8月15日 GitHub ↗ 文档 ↗ dsh-context-surgery
English | 中文
强制改写 DSH 会话的模型可见历史 (surface 替换)。剧情扮演 AI 跑偏(OOC)时把回复改成没跑偏的
版本、retcon 整场戏、修正措辞——模型下一轮请求读到的就是改后的历史,仿佛从未发生过。
回复正文与思考链(reasoning)分开编辑 。
社区插件——非 DeepSeek 官方组件,不代表 DeepSeek 背书。
功能
每条 AI 消息下方的操作按钮 ——聊天视图中每条 AI 消息的操作行(插槽
conversation.chat.assistant-actions,order 20):✏️ 改回复、💡 改思考链、🗑️ 删除。
💡 仅在消息确实带 reasoning 块时出现。
回复与思考链分开编辑 ——part=reply 只改 text 块(保留思考链与工具调用);part=thinking
只改 reasoning 块(留空 = 全部移除);part=all 整条重写为纯文本。
/context 命令全家桶 ——list / edit / think / clear-think / rewrite / delete / replace,
聊天输入框即可完成一切操作。
模型可调用工具 ——context_list / context_edit / context_delete / context_replace,
把同样的能力交给 agent 本身(可用于自我纠错循环)。
HTTP API ——/api/dsh-context-surgery 下的 GET /list、GET /message、
POST /edit|/delete|/replace,供客户端编辑条使用。
立即生效 ——模型下一轮请求读到改后的历史,GUI 对话视图重新折叠显示改后的版本。
日志 append-only ——原始文本从不被抹除;每次改写都是影蔽旧节点的新日志事件,
随时可从日志还原。
仅限顶层会话 ——子代理一律拒绝(requireRootAgent)。
安装
需要 DSH web profile(@deepseek-ai/dsh-web-app)与 Node >= 22.19.0。
克隆或下载本仓库:
git clone https://github.com/WASD258-jpg/dsh-context-surgery.git
安装到 DSH profile 依赖目录(二选一):
方式 A:npm 安装(推荐)
cd "$env:USERPROFILE\.dsh\profiles"
npm install @wasd258/dsh-context-surgery --no-save
方式 B:从源码复制
$src = '.\dsh-context-surgery'
$dst = "$env:USERPROFILE\.dsh\profiles\node_modules\@wasd258\dsh-context-surgery"
New-Item -ItemType Directory -Force -Path "$dst\lib" | Out-Null
Copy-Item "$src\package.json" $dst -Force
Copy-Item "$src\lib\index.js","$src\lib\client.js" "$dst\lib" -Force
Copy-Item "$src\LICENSE","$src\NOTICE" $dst -Force
Linux/macOS 用 ~/.dsh(或 $DSH_HOME)代替 。
@wasd258/dsh-context-surgery · DSH Hub
$env:USERPROFILE\.dsh
把包名追加到 profile 的 package.json 的 dsh.profile.bundles 数组,注册为 bundle:
{
"name": "dsh-profile-web",
"private": true,
"dependencies": {},
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"@wasd258/dsh-context-surgery"
]
}
}
}
重启一次 DSH web(或运行时热装配 bundle),然后刷新浏览器页面以加载客户端模块
(lib/client.js)。
使用
UI:每条消息的操作
在 DSH web 打开一个运行中的顶层会话。
悬停某条 AI 消息的操作行:✏️ 改回复、💡 改思考(仅当存在 reasoning 块)、🗑️ 删除。
点 ✏️ 展开内联文本框(预填当前回复正文);修改后点保存 → “回复已改写 ✓”。
思考链与工具调用不受影响。
点 💡 在文本框里编辑思考链;留空保存 = 移除 → “思考链已改写 ✓”。
点 🗑️ 弹出确认(“删除这条消息(模型视角消失,原始文本仍在日志)?”)→ “已删除 ✓”。
/context 命令 /context(或 /context list、ls、?)列出当前模型可见历史——最后 10 条带 seq:
模型可见上下文共 10 条(显示最后 10 条):
[1] YOU 你好,来扮演图书馆管理员吧。
[2] AI 好的,欢迎光临。今天想找什么书?
[3] YOU 讲讲那本被禁的书。
[4] AI [reasoning] 主角不该知道这本书……那本书只是传说。
[5] TOOL [tool-call toolu_01ABC…]
[6] TOOL [tool-result] {"found": false}
[7] AI 抱歉,馆里没有这本书的记载。
[8] YOU 你刚才不是这么说的。
[9] AI 我记错了,请您原谅。
[10] YOU 继续吧。
行格式 [seq] AI|TOOL|YOU (预览截断到 120 字符;AI=assistant,TOOL=tool/result,YOU=user)。
命令 作用 /context edit 只改回复正文(保留思考链)。→ 已改写 [7] 的回复正文(思考链保留):下一轮模型请求将看到新文本。 /context think 只改思考链(保留回复正文)。→ 已改写 [7] 的思考链(回复正文保留)。 /context clear-think 移除思考链。→ 已移除 [7] 的思考链。 /context rewrite 整条重写为纯文本(part=all)。→ 已整条重写 [7] 为 user 消息:下一轮模型请求将看到新文本。 /context delete 删除该节点(以空 assistant 消息影蔽)。→ 已删除 [7](assistant/message):从模型视角消失。 /context replace 整段连续节点替换为一条新消息。→ 已整段替换 [3,4] 为一条 assistant 消息。
错误以 操作失败: 或 未知子命令: 返回;seq 必须是整数(否则
seq 必须是整数:)。
part 语义 part text 块 reasoning 块 其他块(tool-call 等) 适用 reply(默认)替换 保留 保留 user、assistant thinking保留 替换;留空 = 全部移除 保留 仅 assistant(用户消息没有思考链,会被拒绝) all整条变成单一 text 块 丢弃 丢弃 user、assistant
工具 工具 参数 说明 context_listlimit?按顺序列出全部 surface 节点(或最后 N 条),含 seq/role/text context_editseq、text、role?、part?part 默认 reply;role 缺省沿用原节点角色context_deleteseq以空 assistant 节点影蔽 context_replacestart、end、role、textstart/end 含端点;都必须是当前 surface 节点
示例:context_edit { "seq": 7, "part": "reply", "text": "…" } →
{ "ok": true, "replacementSeq": 11, "shadowedSeq": 7, "role": "assistant", "part": "reply", "text": "…" }。
失败返回 { "ok": false, "error": "…" }。
HTTP API 路由统一挂在 /api/dsh-context-surgery 下:
方法 路径 说明 GET /listsurface 节点;?sessionId=&limit=(limit = 最后 N 条;省略或 0 = 全部) GET /message单条消息拆分为 reply / reasoning;?sessionId=&messageId= POST /edit改写单条;body { sessionId, seq|messageId, part?, role?, text } POST /delete删除单条;body { sessionId, seq|messageId } POST /replace整段替换;body { sessionId, start, end, role, text }
/edit 与 /delete 接受 seq 或 messageId(/edit 的 part 仅 thinking/all 生效,
其余回退为 reply)。
GET /list?sessionId=abc&limit=3 →
{ "ok": true, "sessionId": "abc", "total": 12, "rows": [
{ "seq": 10, "type": "user/message", "role": "user", "text": "…" },
{ "seq": 11, "type": "assistant/message", "role": "assistant", "text": "…", "messageId": "msg_…" }
] }
GET /message?sessionId=abc&messageId=msg_… →
{ "ok": true, "sessionId": "abc", "seq": 11, "messageId": "msg_…",
"type": "assistant/message", "role": "assistant",
"reply": "回复正文", "reasoning": "思考链", "hasReasoning": true }
POST /edit,body { "sessionId": "abc", "seq": 11, "part": "thinking", "text": "…" } →
{ "ok": true, "replacementSeq": 15, "shadowedSeq": 11, "role": "assistant", "part": "thinking", "text": "…" }
状态码 条件 403 非回环源地址(context-surgery API is loopback-only) 403 Host 头不是回环主机名/当前端口(invalid host header,防 DNS rebinding,GET/POST 一视同仁) 403 跨源页面发来的 POST(cross-origin request rejected) 404 会话不在运行(会话 X 不在运行中)/ messageId 不在 surface / 未知路由 415 POST 未带 Content-Type: application/json 400 JSON 无效,或请求体超过 256 KiB 200 + ok:false 操作级失败(seq 已被影蔽、tool/result 节点、对用户消息用 thinking 等) 500 服务器内部错误
工作原理
lib/index.js(host 端)注册 /context 命令、四个 context_* 工具与 HTTP 路由;
lib/client.js(web 端)通过 conversation.chat.assistant-actions 插槽注入每条消息的操作按钮。
模型的消息列表由会话日志的 surface 折叠而来(Session.deriveMessages() → 请求组装)。
日志 append-only,但 surface 支持位置替换 :append 一个带
surfaceOp: { op: "replace", start, end } + sourceEventSeqs(覆盖全部被影蔽节点)的新事件,
即可替换该段 surface——compaction 压缩总结用的正是同一条缝。
改写后:模型下一轮请求读到改后的历史;GUI 对话视图重新折叠;原始文本仍完整保留在事件日志里,
可查可还原。
只能改写运行中的顶层会话 ;子代理一律拒绝。
影蔽区间若包含工具调用,后续轮次引用旧记录可能对不上——优先单条改写;
tool/result 节点不可改写(请改用户消息或 AI 回复)。
隐私与安全
HTTP API 仅限本机回环 且设计上无鉴权 :任何本地进程都能读取会话内容(含思考链)并驱动
历史改写。请在可信的本机环境运行 DSH。
Host 头 + 同源校验防 DNS rebinding 与跨站请求;写路由额外要求 Content-Type: application/json。
context_* 工具把“改写自身历史”的能力交给了模型——仅在信任模型及其输入不会被 prompt
injection 控制时启用(被注入的模型可能被诱导隐藏或篡改历史)。
无遥测、无外部网络请求、不读写凭据。
兼容性
需要 DSH web profile;在 DeepSeek Harness
47f9438
时代实测。
Node >= 22.19.0;版本 0.1.1;MIT。
历史改写走会话 surface 替换缝(与 compaction 同机制);事件日志本身从不被修改。
官方生态要求
许可