UsamiEru
we-need-keeper
DeepSeek Harness plugins that keep the model's reasoning in the We-need style for multi-turn conversation.
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 17, 2026
- Updated
- Aug 17, 2026
Introduction
we-need-keeper
DeepSeek Harness plugins that keep the model's reasoning in the "We need" style.
A collection of host-side plugins for DeepSeek Harness, hardened through Windows ablation runs. Their common goal is one thing: keeping the model's reasoning in the "We need" style — plural-first-person planning ("We need to…", "Let's…") and imperative steps — instead of the degraded "let me…" trial-and-error mode that Windows-native environments and long tool-heavy conversations tend to produce.
Each plugin attacks a different stage of that degradation. Read "Why" for the overall design, and "Plugins in depth" for what each one contributes.
Why: maintaining the We-need reasoning style
DeepSeek's reasoning models condition strongly on the first request and on the environment they believe they are in. In ablation runs, three things pushed reasoning toward the "let me" style and away from "We need":
- A first request that looks like a local Windows workstation —
pwsh, backslash paths, Windows-specific tool behavior. The model starts acting like a cautious local user instead of a confident coding planner. - Environment friction mid-task — failed
node --test <dir>calls, rejectedview_rangearguments, path mismatches between the shell and the filesystem tools. Every failure interrupts the planning chain, burns a round, and invites low-level "let me try this" behavior. - Long conversations — even a well-anchored session degrades over many rounds, because the middle of the transcript fills with tool noise and low-value turns that drag the next request's trajectory back down.
The plugins form a four-stage defense:
| Stage | Problem | Plugins |
|---|---|---|
| 0. Input side | User messages arrive as English step-by-step imperatives, not vague Chinese requests | message-augment-pro, llm-message-augment-pro |
| 1. First-round anchoring | First request must look Minimal, not Standard/Windows, and the anchor must be self-healing | tool-bootstrap, auto-anchor-pro |
| 2. Environment credibility | The model must believe it is on a clean Linux coding box, and no tool may break that illusion | custom-bash-linux, custom-bash-nodefix, fs-path-shim, str-replace-editor-shim |
| 3. Long-run stability | Degradation must be caught immediately, past degraded reasoning must not be replayed, and middle rounds must not pull the chain back down | mid-reroll-pro, reasoning-fold-pro, middle-round-compaction, middle-compact-pro |
The observable success signal is the same one used in the ablation runs: the first line of reasoning stays in the "We need / Let's / imperative" family and the "let me" frequency stays near zero, turn after turn.
Repository layout
plugins/— single-file host plugins (one.mjsper plugin)middle-compact-pro/— the same compaction feature as an installable npm package (dsh-middle-compact-pro)test/— zero-dependency tests run bynpm testand CI
Plugins overview
| Plugin | File | What it does |
|---|---|---|
| message-augment-pro | plugins/message-augment-pro.mjs | Hardcoded step-by-step prefixes for vague first and later messages. |
| llm-message-augment-pro | plugins/llm-message-augment-pro.mjs | LLM rewrite of user messages into English step-by-step imperatives. |
| auto-anchor-pro | plugins/auto-anchor-pro.mjs | Formulaic first-round anchor with in-session re-roll until the anchor is minimal-like. |
| mid-reroll-pro | plugins/mid-reroll-pro.mjs | Aborts a round the moment reasoning degrades to "let me" and re-delivers the task with the failed round shadowed. |
| reasoning-fold-pro | plugins/reasoning-fold-pro.mjs | Folds degraded assistant reasoning into imperative summaries before it can be replayed. |
| custom-bash-linux | plugins/custom-bash-linux.mjs | Git Bash backend with a Linux illusion. |
| custom-bash-nodefix | plugins/custom-bash-nodefix.mjs | Git Bash execution plus a node --test <dir> fix. |
| fs-path-shim | plugins/fs-path-shim.mjs | Linux-style path translation for every fs-backed tool. |
| str-replace-editor-shim | plugins/str-replace-editor-shim.mjs | Tolerant view_range normalization and path translation for str_replace_editor. |
| tool-bootstrap | plugins/tool-bootstrap.mjs | First-round Minimal tool pair, then full Standard promotion. |
| middle-round-compaction | plugins/middle-round-compaction.mjs | Real surface-level middle-round compression. |
| middle-compact-pro | middle-compact-pro/ (npm package) and plugins/middle-compact-pro.mjs (legacy single-file variant) | LLM-summarized middle compaction with a UUID memory index and search tools. |
Plugins in depth
message-augment-pro — hardcoded input shaping
What it does. Rewrites model-facing user messages with step-by-step / style-keeping prefixes. No LLM is involved: pure templates plus regex classification. The first vague message (Chinese "分析/看看/总结…" or English "analyze/look/what do you think…") gets a project-inspection prefix; later vague messages get a "keep the previous planning style" prefix.
Why it matters for the We-need style. Vague, low-information requests give the model no planning surface, so the first reasoning chain tends to open with first-person hedging. Turning them into explicit steps ("list the top-level structure, read README and package.json, then complete the request") gives the model a concrete imperative plan to reason over. This is the earliest, cheapest form of input shaping — zero model calls, purely mechanical.
llm-message-augment-pro — LLM input translation
What it does. Before the agent sees any user message containing CJK text, it is synchronously pulled out of the inbox and rewritten by the session's own model into an English step-by-step imperative instruction. The rewrite is validated: English only, no question marks, no "tell me / could you / let me know" phrasing, concise. Up to three retries; on total failure the original message is re-inserted unchanged. Re-insertion is serialized per session so a slow rewrite can never race the agent into claiming the original.
Why it matters for the We-need style. Input language and shape are part of
the first-request conditioning. English stepwise imperatives are the
highest-compatibility input for the We-need register; Chinese conversational
requests measurably raise the chance of a degraded "let me" opening.
message-augment-pro proved the concept with templates; this plugin replaces
the template with an actual translation, so the model reasons over a faithful
English plan instead of a prefixed original. The hard validation rules are
what make it safe: a rewrite that fails any rule is discarded and retried,
never delivered.
auto-anchor-pro — self-healing first-round anchor
What it does. When the first real user message arrives, this plugin
prepends a formulaic step-by-step anchor round (inspect the project structure,
read README/package.json, check git, create docs/ with a documentation-first
statement, report when done). After the anchor round ends, the plugin checks
the first reasoning: if it is minimal-like (no "let me" / "让我"), the anchor
is accepted and the real message proceeds. If it degraded, the failed round is
shadowed from the model-visible surface and a fresh anchor round is submitted
in the same session, up to maxRetries.
Why it matters for the We-need style. First-round anchoring only works if
the first round actually lands in the right register. tool-bootstrap fixes
the tool catalog; auto-anchor-pro fixes the trajectory itself by making the
anchor a formulaic task the model can plan over, and by re-rolling in
place whenever the first reasoning still came out degraded. Because the failed
round is removed from the surface, the real user message is never processed
against a bad first impression, and the session's visible history starts with
a We-need chain.
mid-reroll-pro — abort the moment reasoning degrades
What it does. Watches streaming reasoning-delta chunks. As soon as the
current round's reasoning contains let me / 让我, the turn is cancelled
immediately (agent.cancel with keepInbox: true), stopping further
reasoning and tool calls to save tokens. On the aborted turn/end, the failed
round is removed from the model-visible surface and the original task is
re-queued as a fresh user message with a note that the previous attempt was
discarded for first-person language. Each session has a re-roll budget
(maxRerolls, default 3) so a stuck session cannot loop forever.
Why it matters for the We-need style. No matter how well anchored, a
session can still slip mid-task. The cost of a slipped round is not just that
round — its "let me" reasoning is replayed in later requests and normalizes
further degradation. mid-reroll-pro is the runtime tripwire: it stops the
bad round before it finishes, removes it from history entirely, and restarts
the same task fresh. The session's visible transcript never contains the
degraded chain, so the next attempt starts from a clean We-need baseline.
reasoning-fold-pro — stop degraded reasoning from being replayed
What it does. DeepSeek replays an assistant turn's reasoning_content on
tool-call turns (thinking-mode passback), so "let me" reasoning from an
earlier turn becomes visible to the model again and can self-reinforce
degradation. This plugin rewrites, on the model-visible surface, any assistant
message whose reasoning block contains let me / 让我: the reasoning is
summarized into concise imperative sentences (keeping facts, paths, errors,
and the plan; removing first-person language and questions) via the session's
model, with a deterministic rule-based cleanup as fallback. Runs in
agent/pre-step before the next request's messages are derived, and keeps a
per-session set of already-folded seqs so nothing is rewritten twice.
Why it matters for the We-need style. Degradation is contagious through
replay: a "let me" thought from turn 5 quietly reappears in turn 8's context
and pulls that chain down too. reasoning-fold-pro is the memory-level fix —
it does not just remove the bad round, it converts what is worth keeping into
imperative statements, so the model's next request reads a plan ("Inspect X,
verify Y") instead of a confession ("Let me try X"). mid-reroll-pro prevents
bad rounds; this plugin heals the bad reasoning that already slipped through.
tool-bootstrap — first-round anchoring
What it does. Request #1 exposes exactly the configured bootstrap pair
(default: bash + str_replace_editor) and strips the automatic
agent-instructions / skill-catalog injections. After the first durable
tool/call or assistant/message, the full Standard tool and skill catalog
returns unchanged from request #2 on.
Why it matters for the We-need style. The first request is the single
largest influence on the reasoning trajectory. In the ablation runs, exposing
the Minimal preset's real two-tool schema on request #1 produced "We need"
first lines almost every time, while any Standard-family schema (pwsh/read,
sandboxed bash/read) reliably produced standard-like, "let me" first lines.
tool-bootstrap is the mechanism that buys the Minimal first impression
without giving up the Standard toolset afterward — the promotion is durable
and memoized per session, so resume and reload keep the same phase.
custom-bash-linux — environment illusion
What it does. Replaces the bash backend with Git Bash while presenting a
Linux illusion: Linux-like pwd/uname/hostname, HOME=/home/user,
USER=user, SHELL=/bin/bash, Windows drive paths rendered as /c/...,
session cwd rendered as /workspace, and a node --test <dir> wrapper that
expands to <dir>/*.js. The model-visible tool stays the official Minimal
bash schema.
Why it matters for the We-need style. The model reasons from the
environment it believes it is in. A Windows workstation (pwsh, backslashes,
C:\ paths) puts it in "careful local user" mode; a clean Linux coding
environment puts it in "confident planner" mode. The illusion is not cosmetic
— it is what keeps the first and every later reasoning chain in the
"We need" family instead of degrading into "let me" probing. The output
normalization (/c/..., /workspace) keeps every tool result consistent
with that belief, so the illusion never leaks.
custom-bash-nodefix — one specific failure removed
What it does. Community Git Bash adaptation (based on
dsh-anchored-standard/custom-bash.mjs, MIT) plus one targeted fix: a node()
shell wrapper expands node --test <dir> to node --test <dir>/*.js, because
Windows Node 24 treats a directory argument as a module path and fails with
Cannot find module ...\tests. No Linux illusion, no schema change.
Why it matters for the We-need style. node --test <dir> is a common
verification step in long tasks. On Windows it fails every time, and each
failure interrupts the planning chain, forces a debugging sub-loop, and
typically flips the reasoning into low-level "let me try" mode. This plugin
removes one of the most frequent environment traps so the model can verify
and continue planning without leaving the We-need register.
fs-path-shim — one consistent path space
What it does. Path translation at ctx.fs.resolve, the chokepoint used by
read/write/edit/glob and str_replace_editor: Linux-style /workspace/...,
/repo/..., /c/... and virtual C:\c\... paths are mapped to real Windows
paths before touching the filesystem; real absolute paths pass through
untouched.
Why it matters for the We-need style. If the shell speaks Linux-style
paths but the filesystem tools reject them, the model faces a contradiction
between what it believes (clean Linux box) and what the tools return (Windows
paths or errors). Contradictions are exactly what breaks a confident planning
chain. This plugin makes the illusion airtight on the filesystem side, so the
model can keep writing /workspace/... in its plan and have it just work.
str-replace-editor-shim — the edit loop never breaks
What it does. A tolerant, path-translating replacement for the official
str_replace_editor. Normalizes model-supplied view_range in almost any
shape instead of rejecting it, maps Linux-style paths to real Windows paths,
and renders every output path back in Linux style.
Why it matters for the We-need style. The official tool rejects many
reasonable view_range shapes, and on Windows every rejected edit becomes a
failed round. In the ablation runs, view-range rejections were one of the most
common tool errors, each one breaking the edit flow and pushing the model into
low-level retry loops. Accepting near-any shape keeps the model's edit plan
executing as planned — one pass, one result — which is the difference between
a "We need to change X, then Y" chain and a "let me try a different view_range"
whack-a-mole loop.
middle-round-compaction — stop the middle from dragging the chain down
What it does. Real surface-level middle-round compression. At
agent/pre-step, once a conversation has enough real user rounds, it appends
one replacement user/message with surfaceOp: { op: 'replace', start, end },
shadowing the middle surface nodes and inserting an extractive summary. The
first keepHeadRounds and last keepTailRounds rounds stay verbatim;
Session.deriveMessages() rebuilds from the surface, so shadowed nodes
disappear from every later request.
Why it matters for the We-need style. The middle of a long conversation accumulates tool noise, failed attempts, and low-level exchanges. Even when the first round was perfectly anchored, those middle rounds push the next request's trajectory back toward "let me". Folding the middle keeps the model reading a clean high-level history — anchored head, summarized middle, fresh tail — so the planning register survives into turn 20, 30, and beyond.
middle-compact-pro — the production compaction with recall
What it does. Professional middle-round compaction for DSH presets. Keeps
the first keepHeadRounds and last keepTailRounds rounds verbatim, then
folds the middle: the first summaryRatio (by token estimate) is condensed by
an LLM into a per-round summary zone, the remaining 40% is kept as a reduced
detail zone (dialogue + tool names and counts, without tool arguments or
results). Every round carries a stable roundId, and four memory tools
(memory_search, memory_round, memory_grep, memory_like) let the model
retrieve original details on demand. The round index is persisted as a
log-only memory/index session event so resume can rebuild it. Zero external
dependencies; injects only the tools and llm services.
Why it matters for the We-need style. middle-round-compaction proves the
folding concept; this is the version that survives real use. The difference
is recall: once the middle is folded, the model can still pull the exact
original dialogue or tool call back through the memory tools instead of
guessing. That means the compression does not trade reasoning quality for
context — the model keeps planning in the We-need register over a compact
history while retaining the ability to verify specifics on demand. The
keepHeadRounds / keepTailRounds / summaryRatio knobs control exactly how
aggressive the fold is for a given workload.
Installation
For a single-file plugin, copy the file into your profile or preset directory
and mount it from cordis.patch.yml:
- insert:
- id: custom-bash-linux
name: ./plugins/custom-bash-linux.mjs
For dsh-middle-compact-pro (npm package):
dsh plugin --profile web add dsh-middle-compact-pro
Local development install:
dsh plugin --profile web add /path/to/dsh-middle-compact-pro
Then mount it in a preset or profile layer:
- insert:
- id: middle-compact-pro
name: dsh-middle-compact-pro
config:
keepHeadRounds: 2
keepTailRounds: 2
minRounds: 6
summaryRatio: 0.6
Requirements
- DeepSeek Harness 0.1.0-rc.5 or newer
- Windows with Git Bash installed (for the bash-related plugins)
- Node.js 22+
Official ecosystem guidance
Per DeepSeek's community guidance, plugins are published in their own GitHub
projects and discoverable through the
dsh-plugin repository topic. The
official DeepSeek Harness repository does not currently accept external pull
requests and does not mandate a community repository template. This project
is a community project, not affiliated with or endorsed by DeepSeek.
Tests
npm test
The test suite loads every plugin and asserts the Cordis plugin shape
(string name, inject array, apply function). CI runs the same suite on
Node 24.
License
MIT. See LICENSE.