dsh-tool-result-pruner-plus
DSH plugin: pruned tool results start with a notice saying what is missing and exactly how to read it back (drop-in replacement for the stock pruner).
- Stars
- 0
- Language
- JavaScript
- Created
- Oct 25, 2026
- Updated
- Oct 25, 2026
Introduction
dsh-tool-result-pruner-plus
Drop-in replacement for DSH's tool-result pruner
(@deepseek-ai/dsh-compaction-tool-result-pruner). When a long tool result is cut to save
context, the result now starts with a notice that says it is incomplete, what is missing,
and exactly how to read it back.
Maintenance: best-effort. Issues may go unanswered; forks are welcome.
Why
The stock pruner keeps the first 4096 and the last 1024 characters of an oversized result and
puts [... tool result middle pruned ...] in between. A model reads 4 KB of normal-looking
output before it meets that marker, with no size, no range and no way back. Small models then
conclude that something is absent, re-run the same command (cut the same way), or work from an
amputated file. See deepseek-harness discussion 8153,
whose head-notice proposal this plugin implements.
What the model sees
[INCOMPLETE tool result (pruned): you see only part of it. The full result was 48970 chars over 851 lines. Shown: chars 1-4096 and chars 47947-48970. NOT shown: chars 4097-47946.
Source: read {"file_path":"/home/u/inventory.txt"} at 2026-10-25T17:26:10.802Z; it may have changed since.
File lines 71-829 are missing or partial: do not conclude that something is absent from the file before checking them. Looking for something specific: search for it first (grep -n), or read only the lines you need. To read all of them: read file_path="/home/u/inventory.txt" offset=71 limit=131, then continue from the next offset (6 reads in all). Do not run the same command or read again unchanged: it is cut the same way.]
then the usual head, a middle marker that names its range
([... chars 4097-47946 not shown; see the notice at the top ...]), and the tail.
readresults: the missing file lines come from theN:prefixes on both sides of the cut (the tail's first line is ignored, since it starts mid-line). The slice size comes from the gap's own average line length and stays under the threshold, so the recovery read is not cut again. If one line is longer than a result can hold, the notice says to search instead.- Other tools: the notice gives the first missing output line and suggests
sed -n 'A,Bp'in pieces,grep, or writing the output to a file. - A result that was already cut is labelled as such, without a line hint (its counts are of what was left, not of the original).
- Budget: the notice fits between head and tail; if needed the head is shortened (never below 1024 chars). When even that is not enough, or anything about a result is unexpected, that result gets the stock cut. One malformed event skips only that result.
Measured effect
Disposable DSH 0.2.1-rc.2 profile, qwen3.5:9b on Ollama (32K window), same prompt each time:
read a 845-line file (45 KB) and say whether any item carries a CODE= value (one does, on
line 517, inside the pruned middle).
| Pruner | Correct answers |
|---|---|
| stock | 0 / 4 (all four answered "none") |
| this plugin | 4 / 4 (each followed the notice: one grep CODE= on the file, then the right answer; 2 tool calls) |
Install
dsh plugin --profile web add github:MathieuPortmann/dsh-tool-result-pruner-plus
The pruner lives inside each agent preset's compaction group, so installing the package is not
enough: in your profile's cordis.patch.yml, wherever a preset lists
- id: tool-result-pruner
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
change the name to 'dsh-tool-result-pruner-plus' (keep the config block). Check with
dsh --profile web --dump-config | grep -A1 'id: tool-result-pruner', then restart. To go back,
restore the stock name.
Configuration
The stock keys, defaults and validation, unchanged: thresholdChars (8192), headChars (4096),
tailChars (1024).
Compatibility
| Component | Supported |
|---|---|
| Node.js | ^22.19.0 || >=24.0.0 |
| DSH | >=0.2.0-rc.2 <0.3.0; extends the installed stock ToolResultPruner class and imports @deepseek-ai/dsh-llm (both declared as optional peerDependencies) |
| Platform | any; pure JavaScript |
Tested on DSH 0.2.1-rc.2.
Permissions and external services
| Capability | Used for |
|---|---|
| Files, network, commands | none |
| Dynamic module loading | loads the stock pruner and @deepseek-ai/dsh-llm from the DSH installation running the plugin; nothing is downloaded |
| Session log | the same compaction/prune + tool/result replace events as the stock pruner; tool-call arguments (cut to 200 chars) are quoted in the notice |
Develop
npm test # 9 standalone tests of lib/notice.js, no DSH needed
License
MIT