Automatic context compression for DeepSeek Harness: compresses tool outputs before they reach the model and keeps every lossy compression reversible via CCR retrieval tools.
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:giter00/dsh-headroom
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Headroom-inspired automatic context compression for DeepSeek Harness (dsh).
Tool outputs are compressed before they reach the model. JSON, search results, logs,
tabular data, and long prose each go through a dedicated deterministic compressor.
Every lossy compression stores the exact original in a local CCR store and injects a
short marker, so the model can call headroom_retrieve(id=…) to recover the original
byte-for-byte.
tool body settles
│
▼
tools/post-execute ← dsh-headroom compresses here
│
▼
tool/result enters session log / model history (compressed content + CCR marker)
│
▼
model calls headroom_retrieve(id=…) when it needs the exact original
Features
Automatic tool-output compression via the
tools/post-executeseam.Content router with specialized compressors:
Content type Strategy JSON array / object SmartCrusher-style pivot: _keys+_rows+_common, long-cell truncationgrep / ripgrep output Fold by file: file (N matches)+line[:col]: restbuild / test / log output Consecutive-repeat folding + error/fail/exception/assertcontext preservedCSV / TSV / markdown tables Keep header + first/last rows, offload the middle Long prose Kompress-style ML compression (default): word-level scoring + must-keep protection + reversible CCR; textStrategy: 'head-tail'switches back to truncationCode Not compressed (no AST compressor in this JS port; line-numbered read/str_replace_editoroutput is detected as code first)File tools Not compressed by default ( read/str_replace_editor/edit/writeand paths matching*.js/*.ts/*.json/*.yml)
Kompress text compression (following Headroom's Kompress-v2-base ML model): the text is split into words, each word is scored (
score = keepProb × (0.5 + 0.5 × spanScore), mirroring the model's token-classifier + span-CNN dual heads), words withscore > 0.5are kept (or the top-k bytargetRatio), and semantically fragile words — numbers, hex, ALLCAPS identifiers, paths, file extensions, CLI flags, CamelCase — are always kept. The default scorer is a deterministic pure-JS heuristic; the real Kompress-v2-base model can be plugged in at the library level viacompressKompressText(text, { scorer })/createKompressCompressor({ scorer })while the pipeline stays identical (the plugin config does not exposescoreryet).
- Reversible compression (CCR):
headroom_retrieve/headroom_compress/headroom_statsmirror Headroom's MCP surface. - Persistence: CCR store defaults to
<DSH_HOME>/storages/dsh-headroom-ccr.json(1 s debounce, atomic replace, configurable TTL and entry cap). - Safe defaults: short text, code, error outputs, excluded tools, and the plugin's own tools are never compressed.
- Cross-platform: pure JavaScript + Node built-ins, no native build step.
The CI matrix lives in
.github/workflows/ci.yml.
How it works
flowchart LR
A[ToolRuntime execution] --> B[tools/post-execute]
B --> C{total text chars >= minChars?}
C -- no --> Z[return unchanged]
C -- yes --> D[ContentRouter]
D --> E[json] --> E1[SmartCrusher pivot]
D --> F[search] --> F1[search fold]
D --> G[log] --> G1[repeat fold + error keep]
D --> H[tabular] --> H1[head/tail keep]
D --> I[text] --> I1[Kompress word scoring + must-keep]
I1 -. no win .-> I2[fallback head/tail]
D --> J[code] --> Z
E1 & F1 & G1 & H1 & I1 & I2 --> K{compressed + marker smaller?}
K -- no --> Z
K -- yes --> L[write CCR store]
L --> M[replace decision.content]
M --> N[model sees compressed content + retrieve marker]
lib/compress.js— pure-function compressors, nonode:*imports.lib/kompress.js— the Kompress-style prose pipeline (word scoring + must-keep protection), ported from Headroom's Kompress-v2-base ML approach; pluggable scorer.lib/ccr.js— in-memory CCR store with debounced persistence.lib/index.js— dsh plugin entrypoint.
Compression results
Stress configuration
node scripts/verify-compress.mjs with minChars=120, maxRows=40, maxCellChars=80, maxTextChars=400:
| Sample | Type | Before (chars) | After (chars) | Saved |
|---|---|---|---|---|
| JSON array, 200 rows | json | 62 491 | 9 302 | 85.1% |
| grep results, 270 hits | search | 10 772 | 4 603 | 57.3% |
| log, 180 lines | log | 3 909 | 1 125 | 71.2% |
| CSV, 201 lines | tabular | 19 814 | 3 029 | 84.7% |
| prose, 400 segments | text | 29 506 | 546 | 98.1% |
| Kompress prose (facts + boilerplate) | text | 16 439 | 2 029 | 87.7% |
| code | code | 493 | 493 | 0% (protected) |
| short text | text | 19 | 19 | 0% (below threshold) |
Token estimates in the script use
chars / 4; real token counts depend on the model tokenizer. Every lossy compression stores the original, so nothing is unrecoverable. The Kompress sample keeps every fragile fact (HTTP/500/hex/path/IndexError) while deleting the repeatedboilerplatephrase(recoverable via CCR).
Default configuration
With defaults (minChars=600, maxRows=80, maxCellChars=200, maxTextChars=2400):
| Sample | Type | Saved |
|---|---|---|
| JSON array, 200 rows | json | 65.6% |
| grep results, 90 hits | search | 41.3% |
| log, 180 lines | log | 56.8% |
| CSV, 201 lines | tabular | 59.8% |
| prose, 400 segments | text | 94.7% |
Effectiveness safety
scripts/verify-compress.mjs also asserts:
- Structured facts (JSON keys/counts, file groups,
ERROR/WARNlines) remain visible after compression. - Code, short text, and error outputs stay byte-identical.
- For every lossy compression,
headroom_retrievereturns the exact original. - A
NEEDLE-42fact hidden in the omitted middle of prose is absent from the compressed view but fully recoverable via CCR. - After Kompress compression, fragile facts (
HTTP,500,0x1f4d2a8b,/var/log/app.log,IndexError) stay visible while the repeatedboilerplatephraseis deleted and recoverable via CCR.
scripts/verify-apply.mjs (requires @deepseek-ai/dsh-tools resolvable) verifies the
real apply() surface: the post-execute listener is installed, a large grep output is
compressed and retrievable, and excluded/own/code/error/short outputs are untouched.
Installation
Requirements
| Item | Requirement |
|---|---|
| Node.js | >= 22.0.0 |
| DeepSeek Harness | >= 0.0.1-rc.5 < 0.2.0-0 (includes 0.1.x prereleases) |
| Package manager | pnpm >= 11 recommended |
| OS | Windows / macOS / Linux |
Recommended
Install directly from GitHub (same command on Windows / macOS / Linux):
dsh plugin --profile web add github:giter00/dsh-headroom
If dsh is not on PATH, invoke the profile CLI directly with the same argument:
# Windows PowerShell
node "$env:USERPROFILE\.dsh\profiles\node_modules\@deepseek-ai\dsh\lib\bin.js" plugin --profile web add github:giter00/dsh-headroom
# macOS / Linux
node "$HOME/.dsh/profiles/node_modules/@deepseek-ai/dsh/lib/bin.js" plugin --profile web add github:giter00/dsh-headroom
pnpm pulls the repository's default branch (
main) and reconciles thedsh-headroombundle into the profile automatically.
Manual
Edit <DSH_HOME>/profiles/web/package.json:
{
"dependencies": {
"dsh-headroom": "github:giter00/dsh-headroom"
},
"dsh": {
"profile": {
"bundles": [
"dsh-headroom"
]
}
}
}
Then:
cd "$DSH_HOME/profiles/web"
pnpm install
Restart dsh.
Uninstall
dsh plugin --profile web remove dsh-headroom
Configuration
Override via cordis.patch.yml:
- id: dsh-headroom
config:
enabled: true
minChars: 600
maxRows: 80
maxCellChars: 200
maxSearchMatchesPerFile: 60
maxLogLines: 80
maxTextChars: 2400
maxTabularLines: 80
excludeTools: []
noFoldForTools: ['read', 'str_replace_editor', 'edit', 'write']
noFoldForPatterns: ['*.js', '*.ts', '*.json', '*.yml', '*.yaml']
markerStyle: full # full | compact
includeErrors: false
textStrategy: auto # auto | kompress | head-tail
kompress:
enabled: true
minWords: 10
chunkWords: 350
scoreThreshold: 0.5
targetRatio: null # null=threshold decision; 0.3=force keep top 30%
mustKeep: true
maxWordChars: 64
ccr:
enabled: true
persist: true
ttlMs: 86400000
maxEntries: 2000
| Field | Default | Description |
|---|---|---|
enabled |
true |
Master switch |
minChars |
600 |
Minimum text-block length before compression is considered |
maxRows |
80 |
Maximum JSON pivot rows kept |
maxCellChars |
200 |
Cell truncation length for JSON (search match lines are kept in full) |
maxSearchMatchesPerFile |
60 |
Search hits kept per file |
maxLogLines |
80 |
Log head/tail budget |
maxTextChars |
2400 |
Prose head/tail budget (head-tail strategy) |
maxTabularLines |
80 |
Tabular head/tail budget |
excludeTools |
[] |
* wildcard patterns; matched tools are never compressed |
noFoldForTools |
['read','str_replace_editor','edit','write'] |
File-content tools are never compressed, keeping read→edit snapshots consistent |
noFoldForPatterns |
['*.js','*.ts','*.json','*.yml','*.yaml'] |
Matched file paths/tool names are never compressed; protects source/config files |
markerStyle |
'full' |
full keeps strategy/savings plus the headroom_retrieve hint; compact emits only id="hr:…" to reduce marker noise |
includeErrors |
false |
Compress error tool outputs too |
textStrategy |
'auto' |
Prose strategy: auto=Kompress first, head/tail fallback; kompress=Kompress only; head-tail=truncation only |
kompress.enabled |
true |
false routes prose to head/tail |
kompress.minWords |
10 |
Skip texts with fewer words (matches Headroom) |
kompress.chunkWords |
350 |
Words per inference chunk (coupled to the model, like Headroom) |
kompress.scoreThreshold |
0.5 |
Keep when score > threshold (matches Headroom's default) |
kompress.targetRatio |
null |
Force keep-ratio via top-k scoring; null = threshold decision |
kompress.mustKeep |
true |
Always keep fragile words (numbers/hex/ALLCAPS/paths/extensions/flags/CamelCase) |
kompress.maxWordChars |
64 |
Longer words (e.g. unbroken CJK runs) are subdivided for scoring |
ccr.enabled |
true |
Disable to turn off lossy compression entirely |
ccr.persist |
true |
Persist the CCR store to disk |
ccr.ttlMs |
86400000 |
Original-content retention |
ccr.maxEntries |
2000 |
Maximum store entries |
Model-visible tools
| Tool | Arguments | Purpose |
|---|---|---|
headroom_retrieve |
id |
Recover the exact original of a compressed tool result |
headroom_compress |
text |
Compress arbitrary text |
headroom_stats |
none | Show process compression statistics |
Marker format:
[headroom: search-fold 12345→987 chars; headroom_retrieve(id="hr:0123456789abcdef")]
Development
node --check lib/index.js && node --check lib/compress.js && node --check lib/ccr.js
node tests/compress.test.js
node scripts/verify-compress.mjs
node scripts/verify-apply.mjs # requires @deepseek-ai/dsh-tools
Known limitations
- The default scorer is a heuristic simulation, not real model inference:
lib/kompress.jsfaithfully ports Headroom's Kompress-v2-base pipeline structure and scoring formula, but the default scores come from a deterministic pure-JS heuristic. To get real model semantics, plug an ONNX/PyTorch scorer at the library level. - Kompress output is a fragment of kept words: the default threshold deletes many ordinary words aggressively, so readability is limited — it is designed for model consumption plus CCR retrieval of the exact original when needed.
- Conservative no-compression cases: texts made entirely of must-keep tokens, or purely repeated CJK text, fall back to head/tail or pass through unchanged so content is never wiped to zero.
- Template text is not de-duplicated: repeated numbers/identifiers are each preserved by must-keep semantics, so templated output may keep many repeated fact tokens and compress less than ordinary prose.
Differences from Headroom
| Dimension | Headroom | dsh-headroom |
|---|---|---|
| Integration | proxy / wrap / MCP / SDK | native dsh plugin on tools/post-execute |
| JSON | SmartCrusher (Rust core) | JS pivot (_keys / _rows / _common) |
| Code | AST CodeCompressor | skipped by default |
| Text | Kompress-v2-base ML model (ONNX/PyTorch) | same Kompress pipeline (word scoring + must-keep + threshold/top-k); pure-JS heuristic scorer by default, the real model can be plugged in via createKompressCompressor({ scorer }) (not exposed in plugin config yet) |
| Reversibility | CCR | local CCR store + headroom_retrieve |
| Native deps | some extras (onnxruntime/torch) | none with the default heuristic; only when plugging in the real model |
License
This project is a derivative work of Headroom (Apache-2.0), so it is released under the Apache License 2.0 as well, keeping license compatibility and satisfying upstream compliance requirements. See NOTICE for copyright and upstream attribution.
Acknowledgements
Design and compression strategies are inspired by Headroom (Apache-2.0).
Links
More in this category
volcengine/OpenViking#examples/dsh-memory-plugin★ 28995
OpenViking memory and context bundle for DeepSeek Harness: pre-step auto-recall and profile injection, session capture, `viking://` URI guarding, and recall/write memory tools backed by an OpenViking server.
vectorize-io/hindsight#coding-agents★ 20139
Hindsight, agent memory that learns: long-term project memory with auto recall and retain, knowledge pages, deep reflection, and per-repo memory banks.
Ikalus1988/MisakaNet★ 405
Failure-recovery memory: search and record failure-recovery lessons from real engineering sessions, with BM25 + semantic RAG retrieval and a lessons knowledge base.
text2future/flowix#dsh-flowix-memory★ 316
Registers the local flowix-cli MCP server so the agent can search, read, create, and edit Flowix memos and mind-map artifacts.
dsh-engramory★ 155
The Engramory curated-memory discipline as an installable plugin ([npm: dsh-engramory](https://www.npmjs.com/package/dsh-engramory)): a deterministic 200-line / 25 KB cap on the `MEMORY.md` index via `ctx.tools.guard()` — growth denied, a shrinking rewrite always passes — plus the protocol registered as a runtime skill. The store is plain markdown, one file per fact, shared with Claude Code, Codex, Kiro, and OpenClaw.
omdsh-dev/dsh-mnemon★ 92
Cross-agent, local-first persistent memory plugin for DeepSeek Harness (DSH), powered by Mnemon. It shares long-term memory across Mnemon-enabled agents and adds runtime memory, searchable project documents, semantic recall, knowledge graph, and a Sidebar UI.