DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

WASD258-jpg /

dsh-context-surgery

Topic repository only

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

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@c4eaf19d

dsh-context-surgery

中文 | English

Surgical rewriting of the model-visible conversation history of a DSH session (surface replacement): fix an out-of-character reply, retcon a scene, or correct wording — the model's next request reads the edited history as if it had always been that way. Reply text and the reasoning chain are edited separately.

This is a community project. It is not an official DeepSeek plugin and does not imply any endorsement by DeepSeek.

Features

  • Per-message surgery buttons — every AI message's action row (slot conversation.chat.assistant-actions, order 20): ✏️ edit reply, 💡 edit thinking (shown only when the message has a reasoning block), 🗑️ delete.
  • Separate reply / thinking editing — part=reply rewrites only text blocks (keeps reasoning and tool calls); part=thinking only reasoning blocks (empty text removes them all); part=all rewrites the whole message as plain text.
  • /context command family — list / edit / think / clear-think / rewrite / delete / replace from the chat input.
  • Model-callable tools — context_list, context_edit, context_delete, context_replace (for self-correction loops).
  • HTTP API — GET /list, GET /message, POST /edit|/delete|/replace under /api/dsh-context-surgery.
  • Immediate effect — the next model request reads the edited history; the GUI conversation view refolds.
  • Append-only log — the original text is never erased; every rewrite is a new log event shadowing old nodes.
  • Top-level sessions only — subagents are rejected (requireRootAgent).

Install

Requires the DSH web profile (@deepseek-ai/dsh-web-app) and Node >= 22.19.0.

  1. Clone or download this repository:

    git clone https://github.com/WASD258-jpg/dsh-context-surgery.git
    
  2. Install into the DSH profile dependency directory (choose one):

    Option A: npm install (recommended)

    cd "$env:USERPROFILE\.dsh\profiles"
    npm install @wasd258/dsh-context-surgery --no-save
    

    Option B: copy from source

    $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
    

    On Linux/macOS use ~/.dsh (or $DSH_HOME if set) instead of $env:USERPROFILE\.dsh.

  3. Register the package as a bundle: append the name to dsh.profile.bundles in the profile's package.json:

    {
      "name": "dsh-profile-web",
      "private": true,
      "dependencies": {},
      "dsh": {
        "profile": {
          "bundles": [
            "@deepseek-ai/dsh-base",
            "@deepseek-ai/dsh-web-app",
            "@wasd258/dsh-context-surgery"
          ]
        }
      }
    }
    
  4. Restart DSH web once (or hot-assemble the bundle at runtime), then refresh the browser page so the client module (lib/client.js) loads.

Usage

UI: per-message actions

  1. Open a running top-level session; hover an AI message's action row: ✏️ / 💡 / 🗑️.
  2. ✏️ opens a textarea prefilled with the reply; edit and click 保存 (Save) → "回复已改写 ✓" (reasoning and tool calls kept).
  3. 💡 edits the reasoning chain; leave empty and save to remove it → "思考链已改写 ✓".
  4. 🗑️ asks for confirmation, then deletes → "已删除 ✓".

/context commands

/context (or list / ls / ?) prints the current model-visible history — the last 10 rows with 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 继续吧。

Row format [seq] AI|TOOL|YOU <preview> (120-char truncation); the plugin's status strings are in Chinese.

Command Effect
/context edit <seq> <text> Rewrite only the reply (keeps reasoning) → 已改写 [7] 的回复正文(思考链保留):下一轮模型请求将看到新文本。
/context think <seq> <text> Rewrite only the thinking chain → 已改写 [7] 的思考链(回复正文保留)。
/context clear-think <seq> Remove the thinking chain → 已移除 [7] 的思考链。
/context rewrite <seq> <user|assistant> <text> Rewrite the whole message (part=all) → 已整条重写 [7] 为 user 消息:下一轮模型请求将看到新文本。
/context delete <seq> Delete the node (empty assistant shadow) → 已删除 [7](assistant/message):从模型视角消失。
/context replace <start> <end> <user|assistant> <text> Replace a contiguous range → 已整段替换 [3,4] 为一条 assistant 消息。

Errors: 操作失败:<原因> or 未知子命令:<op>; seq must be an integer.

part semantics

part text blocks reasoning blocks other blocks (tool-call …) applies to
reply (default) replaced kept kept user, assistant
thinking kept replaced; empty text removes them all kept assistant only (user messages have no reasoning chain)
all one text block dropped dropped user, assistant

Tools

Tool Parameters Notes
context_list limit? surface rows in order (or last N): seq, role, text
context_edit seq, text, role?, part? part defaults to reply
context_delete seq shadowed by an empty assistant node
context_replace start, end, role, text inclusive; both must be current surface nodes

context_edit { "seq": 7, "part": "reply", "text": "…" } → { "ok": true, "replacementSeq": 11, "shadowedSeq": 7, "role": "assistant", "part": "reply", "text": "…" }; failures return { "ok": false, "error": "…" }.

HTTP API

All routes are under /api/dsh-context-surgery:

Method Path Description
GET /list surface rows; ?sessionId=&limit= (limit = last N; omit/0 = all)
GET /message one message split into reply/reasoning; ?sessionId=&messageId=
POST /edit rewrite one node; body { sessionId, seq|messageId, part?, role?, text }
POST /delete delete one node; body { sessionId, seq|messageId }
POST /replace replace a range; body { sessionId, start, end, role, text }

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": "reply text", "reasoning": "thinking chain", "hasReasoning": true }

POST /edit with { "sessionId": "abc", "seq": 11, "part": "thinking", "text": "…" } → { "ok": true, "replacementSeq": 15, "shadowedSeq": 11, "role": "assistant", "part": "thinking", "text": "…" }

Errors:

Status Condition
403 non-loopback source (context-surgery API is loopback-only)
403 Host header not loopback/current port (invalid host header)
403 POST from a cross-origin page (cross-origin request rejected)
404 session not running / messageId not in surface / unknown route
415 POST without Content-Type: application/json
400 invalid JSON body, or body larger than 256 KiB
200 + ok:false operation-level failure (seq shadowed, tool/result node, thinking on a user message, …)
500 unexpected server error

How it works

  • lib/index.js (host) registers the /context command, the four context_* tools and the HTTP routes; lib/client.js (web) injects the per-message buttons via the conversation.chat.assistant-actions slot.
  • The model's message list is derived from the session log's surface (Session.deriveMessages() → request assembly). The log is append-only, but the surface supports positional replacement: appending an event with surfaceOp: { op: "replace", start, end } + sourceEventSeqs (covering every shadowed node) replaces that surface range — exactly the seam compaction summaries use.
  • After a rewrite the next request reads the edited history, the GUI refolds, and the original text stays in the log.
  • Only the running top-level session may be edited; subagents are rejected. Shadowing ranges that contain tool calls can leave later tool references inconsistent — prefer single-message edits; tool/result nodes cannot be rewritten.

Privacy & security

  • The HTTP API is loopback-only and unauthenticated by design: any local process can read session content (including reasoning chains) and drive rewrites. Run DSH in a trusted local environment only.
  • Host-header + same-origin checks block DNS-rebinding and cross-site requests; writes need application/json.
  • The context_* tools give the model power to rewrite its own history — enable only where you trust the model and its inputs not to be prompt-injected (a compromised model could be steered to hide or alter history).
  • No telemetry, no external network requests, no credential access.

Compatibility

  • Requires a DSH web profile; verified against DeepSeek Harness commit 47f9438.
  • Node >= 22.19.0; version 0.1.1; MIT.
  • Rewrites ride the session surface-replacement seam (same mechanism as compaction); the log itself is never modified.

Official ecosystem requirements

DeepSeek suggests community authors publish plugins in their own GitHub repositories and add the dsh-plugin topic for discoverability; the official repository does not accept external PRs. See CONTRIBUTING.zh.md.

License

MIT — see LICENSE. Portions reference DeepSeek Harness; provenance and the non-affiliation statement are in NOTICE.

—/ 5

No ratings yet

Manifest verification required

Commit c4eaf19da0a0

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout