편집자 노트

WASD258-jpg/dsh-context-surgery

Surgical rewriting of the model-visible conversation history of a DSH session (surface replacement). Edit reply vs reasoning chain separately.

이것은 DeepSeek Harness(DSH) 플러그인입니다. 이 사이트는 GitHub README, 설치 정보, 유지보수 상태, 공개 보안 시그널을 모아 보여줍니다.

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 /listGET /messagePOST /edit|/delete|/replace,供客户端编辑条使用。
  • 立即生效——模型下一轮请求读到改后的历史,GUI 对话视图重新折叠显示改后的版本。
  • 日志 append-only——原始文本从不被抹除;每次改写都是影蔽旧节点的新日志事件, 随时可从日志还原。
  • 仅限顶层会话——子代理一律拒绝(requireRootAgent)。

安装

需要 DSH web profile(@deepseek-ai/dsh-web-app)与 Node >= 22.19.0。

  1. 克隆或下载本仓库:

    git clone https://github.com/WASD258-jpg/dsh-context-surgery.git
    
  2. 安装到 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)代替 $env:USERPROFILE\.dsh

  3. 把包名追加到 profile 的 package.jsondsh.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"
          ]
        }
      }
    }
    
  4. 重启一次 DSH web(或运行时热装配 bundle),然后刷新浏览器页面以加载客户端模块 (lib/client.js)。

使用

UI:每条消息的操作

  1. 在 DSH web 打开一个运行中的顶层会话。
  2. 悬停某条 AI 消息的操作行:✏️ 改回复、💡 改思考(仅当存在 reasoning 块)、🗑️ 删除。
  3. 点 ✏️ 展开内联文本框(预填当前回复正文);修改后点保存 → “回复已改写 ✓”。 思考链与工具调用不受影响。
  4. 点 💡 在文本框里编辑思考链;留空保存 = 移除 → “思考链已改写 ✓”。
  5. 点 🗑️ 弹出确认(“删除这条消息(模型视角消失,原始文本仍在日志)?”)→ “已删除 ✓”。

/context 命令

/context(或 /context listls?)列出当前模型可见历史——最后 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 <seq> <文本>只改回复正文(保留思考链)。→ 已改写 [7] 的回复正文(思考链保留):下一轮模型请求将看到新文本。
/context think <seq> <文本>只改思考链(保留回复正文)。→ 已改写 [7] 的思考链(回复正文保留)。
/context clear-think <seq>移除思考链。→ 已移除 [7] 的思考链。
/context rewrite <seq> <user|assistant> <文本>整条重写为纯文本(part=all)。→ 已整条重写 [7] 为 user 消息:下一轮模型请求将看到新文本。
/context delete <seq>删除该节点(以空 assistant 消息影蔽)。→ 已删除 [7](assistant/message):从模型视角消失。
/context replace <start> <end> <user|assistant> <文本>整段连续节点替换为一条新消息。→ 已整段替换 [3,4] 为一条 assistant 消息。

错误以 操作失败:<原因>未知子命令:<op> 返回;seq 必须是整数(否则 seq 必须是整数:<值>)。

part 语义

parttext 块reasoning 块其他块(tool-call 等)适用
reply(默认)替换保留保留user、assistant
thinking保留替换;留空 = 全部移除保留仅 assistant(用户消息没有思考链,会被拒绝)
all整条变成单一 text 块丢弃丢弃user、assistant

工具

工具参数说明
context_listlimit?按顺序列出全部 surface 节点(或最后 N 条),含 seq/role/text
context_editseqtextrole?part?part 默认 replyrole 缺省沿用原节点角色
context_deleteseq以空 assistant 节点影蔽
context_replacestartendroletextstart/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 接受 seqmessageId/editpartthinking/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
403Host 头不是回环主机名/当前端口(invalid host header,防 DNS rebinding,GET/POST 一视同仁)
403跨源页面发来的 POST(cross-origin request rejected
404会话不在运行(会话 X 不在运行中)/ messageId 不在 surface / 未知路由
415POST 未带 Content-Type: application/json
400JSON 无效,或请求体超过 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 同机制);事件日志本身从不被修改。

官方生态要求

按 DeepSeek 当前建议,社区插件发布在各自的 GitHub 仓库并添加 dsh-plugin topic 以便被发现。官方仓库不接受外部 PR, 也不强制社区插件模板。参见 CONTRIBUTING.zh.md

许可

MIT —— 见 LICENSE。部分内容参考 DeepSeek Harness;来源与免责声明见 NOTICE

REPOSITORY SIGNALS

보안 및 설치 증거

이 점수는 공개 저장소 메타데이터와 이 사이트에 등록된 설치 증거에만 기반하며, 코드 보안 감사와 다릅니다.

출처 추적 가능

공개 플러그인 카탈로그에서 왔으며, 공개 GitHub 저장소로 연결됩니다.

라이선스

GitHub 메타데이터에서 라이선스가 감지되지 않았습니다.

유지보수 활동

최근 180일 내 코드 업데이트가 있습니다.

설치 증거

재현 가능한 정확한 설치 메타데이터가 아직 등록되지 않았습니다. 저장소 설명에 따라 직접 확인하세요.

설치 라이프사이클 스크립트

검사한 패키지 메타데이터에 설치 라이프사이클 스크립트가 선언되지 않았습니다.

주의 사항missing-license