dsh-trim
v0.1.36
Published
Adaptive, fidelity-preserving tool-result trimmer for DeepSeek Harness. Collapses redundancy deterministically, never drops error signals, and spills the full original output so no information is ever lost.
Maintainers
Readme
dsh-trim
Adaptive, fidelity-preserving tool-result trimmer for DeepSeek Harness.
dsh-trim saves input tokens by collapsing redundancy in tool results, deterministically and without losing data. Every original is spilled, so the model can always read the full output when it matters. It ships a savings dashboard with auto pricing, peak/off-peak splits, and charts.
Features
- Deterministic compaction. Same input always gives the same output, so DeepSeek's strict prefix cache keeps hitting on replay.
- Adaptive by default. Mid-size results pass through untouched while the session context is fresh; compaction turns on as the context fills up.
- Lossless escape hatch. Any content that is trimmed is spilled first. The full original is always one read away.
- Format aware. Long-form
git status,ls -lalistings, and unified diffs become compact without losing their meaning. Everything else keeps its unique content. - Savings dashboard. Per-session stats in a storage domain (never the session log), auto-fetched DeepSeek prices, peak/off-peak splits, filters, charts, and CSV export.
How it works
The plugin listens on tools/post-execute, before the built-in
spill-policy:
tool result ──> small? ── pass through (no risk, no cost)
└─> mid-size? ── compact deterministically ──> still big? ── spill + preview
└─> huge? ── spill full original + bounded preview- Small results (below
compactAboveChars, default 1200) pass through byte-identical. - Mid-size results get deterministic compaction in adaptive mode:
- ANSI and OSC escapes are removed.
- Blank-line runs collapse.
- Consecutive identical lines fold into
line (repeated xN), only when that saves bytes. Unique lines are never dropped. - Long-form
git statusbecomes the short form. ls -lalistings become size lists.- Unified diffs lose redundant headers and long context runs collapse to a count marker.
- Over the inline cap, or any content trimmed, the full original is
spilled to
ctx.spillStore. The model sees a bounded head/tail preview or the compacted text plus a spill locator. End-of-result markers such as[exit code: N]always stay.
Savings dashboard
The web profile serves a self-contained page at:
http://127.0.0.1:3080/dsh-trim- Tiles: total saved, saved during peak, saved during off-peak, data saved, sessions with savings, and estimated dollars (each window priced at its own rate).
- Table: per session, with a "before → after" token column, a total row, and a detail view per session (click a row to see each trim with its time, tool, and sizes).
- Chart: stacked bars (peak and off-peak per bucket), with hour, day, week, month, and year ranges.
- Filters: session, billing window (peak / off-peak), range, price
override (
?price=), auto-refresh, CSV export. - Auto pricing: fetches the official DeepSeek pricing page (cached 6
hours, fail open), uses
priceModelinput miss prices, and shows peak hours in your own time zone. - Design: follows the DeepSeek Harness design tokens, light and dark.
Stats live in a trim_stats storage domain keyed by session id. A
third-party plugin cannot write custom events into the session log (there is
no ignorable registration surface), so stats deliberately stay outside it.
Savings recorded before the peak/off-peak split existed are shown with a
note; new trims fill the split in.
Install (web profile)
Two steps: install the package into the profile, then mount it as a plugin row. This is the standard dsh way; it cannot be one step because the row is how the harness composes plugins.
dsh plugin --profile web add dsh-trim
# Local development only:
# dsh plugin --profile web add file:/path/to/dsh-trimThen add this to ~/.dsh/profiles/web/cordis.patch.yml:
- insert:
- id: trim
name: dsh-trim
config:
compactAboveChars: 1200
maxInlineChars: 8000Restart the GUI. Verify with dsh --profile web --dump-config.
Configuration
| Key | Default | Meaning |
|---|---|---|
| compactAboveChars | 1200 | Below this size, results pass through untouched. |
| maxInlineChars | 8000 | Inline cap; above it, spill plus preview, even in a fresh context. |
| skipTools | ["read"] | Tools left verbatim. |
| compactTools | [] | When non-empty, only these tools are trimmed. |
| keepDiffContextLines | 2 | Unchanged lines kept around diff changes before the rest collapse. |
| adaptive | true | Quality first: pass mid-size results through while the session is fresh. |
| adaptivePressureTokens | 20000 | Heuristic context tokens. Below this, the soft band is skipped. Keep it well under your model's compaction threshold (DSH compacts around 0.8 of the window). |
| pricePerMillionTokens | 0 | Input price per million tokens for the dollar savings estimate. 0 hides dollars. |
| autoPrice | true | Fetch current DeepSeek input prices from the official pricing page. |
| priceModel | "flash" | Which model's prices the dashboard uses: flash, pro, or vision. |
Quality guarantees
- Compaction never removes unique content, only exact redundancy.
- Any step that drops text is preceded by a spill of the full original.
compact()never returns something larger than its input.- The
readtool is skipped, so deliberate file reads stay verbatim.
Reliability
- Fail open. An unexpected listener error keeps the original result and logs the cause. Trimming can never turn a successful tool call into an error.
- Config validated at load time. Invalid values fail the boot loudly.
- Deterministic and idempotent. Compacting an already compacted result is a no-op, which keeps the provider cache hitting on replay.
- Linear time. Every transform is a single pass; no retained state between calls; safe for concurrent tool results.
- Contained spill failures. A failing spill store degrades to the compacted inline text.
- Fuzz-tested. A seeded battery asserts never-grow and idempotence over mixed ANSI, unicode, CRLF, and diff-shaped inputs.
- Contract-verified. Integration points are checked against the
harness's own type contracts (storage-domain
KvTable, webserver routes, zod record schemas).
Performance
Measured with npm run bench (Node v26.5.0, macOS, synthetic worst cases).
The harness bound is 4000ms per case; real numbers sit 30 to 140x below it.
| Input | Time | Throughput | Result | |---|---|---|---| | 1MB unique lines | 16ms | 54MB/s | unchanged (100%) | | 1MB repeated lines | 6ms | 114MB/s | collapses to ~0 | | 1MB diff-shaped | 31ms | ~10MB/s | 74%, lossy | | 1MB single line, no newline | 3ms | 361MB/s | unchanged | | 10MB unique lines | 138ms | 64MB/s | unchanged | | 10MB repeated lines | 59ms | 119MB/s | collapses to ~0 | | preview of 10MB, capped 8KB | 76ms | | 7.7KB inline | | 200 parallel 200KB results | 422ms wall | | |
Peak retained heap after a 10MB compaction measures at 0MB (transient allocations are collected; nothing is cached between calls).
Failure modes
| Condition | Behavior |
|---|---|
| Spill store not mounted | Compacted text stays inline, no pointer. |
| Spill write fails | Same, plus a warning log. |
| Unexpected listener error | Original result kept, warning log, fail open. |
| Invalid config | Boot fails with a clear message (fail fast). |
| Result contains non-text blocks | Left untouched. |
| Result already spilled by another policy | Skipped. |
| read tool call | Always skipped, verbatim. |
| Plugin removed mid-session | Remaining listeners unaffected; results pass through. |
| Pricing fetch fails | Dashboard falls back to the configured price. |
Testing
npm test # 62 plain assertions, no framework
npm run bench # performance harness with regression boundsFor a complete walkthrough, from install and cleanup to dashboard use and publishing, see GUIDE.md.
Publishing
MIT-licensed, one dependency (zod). The repository is live with CI running
npm test and npm run bench on every push (Node 18 and 20). To publish:
npm login(one time).npm publish. Thefilesfield ships only the plugin, tests, bench, and docs;npm pack --dry-runverifies the contents first.- Consumers install with
dsh plugin --profile <name> add dsh-trimand add the patch row from the install section.
2FA note: interactive npm publish asks for the email one-time code. A
scripted or CI publish needs a granular access token created with "Bypass
2FA" enabled; that flag is only set at creation time and only works on
tokens with write access. Revoke the token right after the publish.
Cost notes
Deterministic compaction shrinks the first-miss bytes of tool results, the
part of a DeepSeek cache that cannot be avoided (community-measured pattern:
42,299 chars down to 7,885, with identical replay hashes, dsh-handbook
section 14.1). The other cost levers, such as off-peak scheduling, cache hit
rate, and prefix slimming, are covered in COST-GUIDE.md.
License
MIT. See LICENSE.
