zeranhub/dsh-context-shaping ↗★ 0

dsh-context-shaping

就地改写或删除会话历史中的回复文本与思考链 适合需要通过人工干预和微调来引导AI后续行为的用户。

包名
dsh-context-shaping
兼容性
待验证
版本
0.4.2
许可证
NOASSERTION
最近更新
2026年10月7日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:zeranhub/dsh-context-shaping

Usage

Per-message buttons (web GUI)

The plugin registers into the conversation.chat.assistant-actions slot (order: 20), so each assistant message gets an action row:

ButtonAction
✏️Rewrite this reply. Opens an inline text box prefilled with the current reply text; Save → "Reply rewritten ✓". The reasoning chain and tool calls are kept.
💡Rewrite this reasoning chain. Shown only when the message actually has a reasoning block; saving an empty text removes it.
↩️Restore the content this rewrite shadowed. Shown only on rewrite nodes.
🗑️Delete this message. Asks for confirmation first; the message disappears from the model's view.
badgerewritten marks a node that is itself a rewrite; its original text is still in the event log.

Button labels and tooltips follow the browser language (zh* → Chinese, otherwise English).

The host composes the row as [clock] copy · extraActions · branch, and our slot's entry is that extraActions — so these buttons sit immediately to the right of the copy icon.

Edit your own message (web GUI)

The AI's buttons are per-message; your own messages have no action row a plugin can extend in this DSH build (see Notes). Instead the plugin adds a small ✏️ Edit mine control in the composer's tool row (conversation.input.left), which opens a full-width editor above the card (conversation.input.dock):

  1. click Edit mine — it loads your most recent own message (injected user/message context is skipped);
  2. change the text and press Save;
  3. the message is rewritten in the model-visible history — nothing is sent, no new turn starts, and the next model request reads the edited text.

/shape command

/shape on its own (or /shape list) prints the current model-visible nodes — the last 10, as [seq] AI|TOOL|YOU , with rewritten nodes marked — followed by the usage list.

CommandEffect
/shape, /shape list, ls, ?List the current model-visible nodes (last 10) with seq, role badge and a 120-character preview.
/shape show Print one node's full reply and reasoning chain (and whether it carries tool blocks).
/shape edit Rewrite the reply text only; reasoning chain and tool calls are kept.
/shape think Rewrite the reasoning chain only; the reply text is kept.
/shape clear-think Remove the reasoning chain.
/shape rewrite Rewrite the whole node as plain text (part=all). This is the only command that may change a node's role.
/shape delete Remove the node from the model's view.
/shape replace Replace the contiguous range start..end (inclusive, current surface order) with one message.
/shape history [n] (alias log)Rewrite audit trail, newest first (default 10, clamped to 1–50).
/shape undo [n] (alias restore)Restore the n-th most recent rewrite (default 1).

`` is taken verbatim from the command line, spaces included; seq arguments must be integers. Failures are reported as 操作失败: and unknown subcommands as 未知子命令: — command output, error strings and audit lines are in Chinese in 0.2.0.

Model tools

ToolParametersNotes
shape_listlimit?List surface nodes in order (or the last N) with seq, role, text. Read-only.
shape_editseq, text, part? (reply/thinking/all), role?part defaults to reply; role is only honored with part=all.
shape_deleteseqShadow one node with an empty assistant message.
shape_replacestart, end, role, textBoth endpoints inclusive and must be current surface nodes.
shape_historylimit?Read the rewrite audit trail. Read-only.
shape_restoreseq or indexUndo the rewrite at seq, or the index-th most recent rewrite (1 = most recent).

All six are refused when exposeTools: false; the four mutating tools require a running top-level session. Failures come back as { "ok": false, "error": "…" }, successes as { "ok": true, "replacementSeq": …, "shadowedSeq": … } and similar fields.

HTTP API

Routes are registered under /api/dsh-context-shaping (prefix registration). GET routes are read-only, POST routes rewrite history.

MethodPathParameters
GET/list (or /)?sessionId=&limit= — limit = last N rows; omitted or 0 = all.
GET/last-user?sessionId= — the most recent message you sent, for the composer's Edit mine control: { ok, found, seq?, messageId?, text?, isRewritten?, sourceKind? }. Skips injected user/message context. Reading only; no top-level check needed.
GET/message?sessionId=&messageId= — one node split into reply / reasoning.
GET/history?sessionId= — audit trail: in-process journal plus records recovered from the log.
POST/edit{ sessionId, seq | messageId, part?, role?, text }
POST/delete{ sessionId, seq | messageId }
POST/replace{ sessionId, start, end, role, text }
POST/restore{ sessionId, seq | messageId }
// GET /api/dsh-context-shaping/list?sessionId=abc&limit=2
{ "ok": true, "sessionId": "abc", "total": 12, "rows": [
  { "seq": 10, "type": "user/message", "role": "user", "text": "…", "isRewritten": false },
  { "seq": 11, "type": "assistant/message", "role": "assistant", "text": "…", "messageId": "msg_…", "isRewritten": true }
] }

// POST /api/dsh-context-shaping/edit
// { "sessionId": "abc", "seq": 11, "part": "thinking", "text": "…" }
{ "ok": true, "replacementSeq": 15, "shadowedSeq": 11, "role": "assistant", "part": "thinking", "text": "…" }
StatusCondition
403Request is not from loopback (context-shaping API is loopback-only).
403Host header is not a loopback hostname on the current port (invalid host header) — DNS-rebinding defence, applied to GET and POST alike.
403POST from a cross-origin page (cross-origin request rejected).
403httpEnabled: false, or POST while httpWrite: false.
415POST without Content-Type: application/json.
400Body is not valid JSON (a body over 256 KiB is rejected the same way).
404Session not running (会话 不在运行中), messageId not on the surface, or unknown route.
200 + ok: falseOperation-level failure: shadowed seq, tool/result node, thinking on a user message, a subagent, and so on.
500Internal error.

Configuration

Set these in the DSH settings page (the plugin registers a settings section, namespace context-shaping) or in the profile config layer. Everything has a default, so the plugin works unconfigured; a missing settings service is harmless (defaults stay in effect).

KeyDefaultEffect
exposeToolstrueRegister the shape_* tools for the model. When false, model calls are refused.
allowToolNodesfalseAllow whole-message rewrite, delete and range replace on messages carrying tool calls (this hides tool records from the model).
allowRoleChangetrueAllow the command and the GUI to change a message's role (requires part=all).
allowModelRoleChangefalseAllow the model to change a message's role (off by default, to prevent forged user turns).
httpEnabledtrueServe the /api/dsh-context-shaping routes.
httpWritetrueAllow HTTP rewrite / delete / restore; false makes the API read-only.
auditSize200Rewrite records kept per session.
maxTextLength200000Character limit for a single rewrite's text.