DeepSeek Harness plugin

dsh-auto-compact-zhuhb

DeepSeek Harness plugin: automatically invoke the built-in compaction engine when a session's measured context reaches a configurable absolute token threshold (default 256K)

Jump to install

Source facts

Repository
Zh-U-hB/dsh-auto-compact
Latest update
Aug 16, 2026
Category
Memory
GitHub stars
0
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/Zh-U-hB/dsh-auto-compact
Plugin: dsh-auto-compact-zhuhb
Author: Zh-U-hB

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.mdSource · read only
README language

dsh-auto-compact

[English](#dsh-auto-compact) | 中文

A DeepSeek Harness plugin that automatically compacts a session once its measured context reaches a configurable absolute token threshold.

It does not invent a new summarizer: it drives the harness's built-in compaction engine — the exact ctx.compaction service behind the built-in /compact command — through the same durable, lock-protected surface replacement path. The only thing this plugin adds is a user-controlled absolute threshold policy.

Default threshold: 262144 tokens (256K).

---

Table of contents

  • [Why it exists](#why-it-exists)
  • [How it works](#how-it-works)
  • [Coverage: every session, every preset](#coverage-every-session-every-preset)
  • [Features](#features)
  • [Requirements](#requirements)
  • [Installation](#installation)
  • [Configuration](#configuration)
  • [Behavior and semantics](#behavior-and-semantics)
  • [Logging](#logging)
  • [Uninstallation](#uninstallation)
  • [Local development and tests](#local-development-and-tests)
  • [Repository layout](#repository-layout)
  • [Compatibility](#compatibility)
  • [Troubleshooting](#troubleshooting)
  • [Security model](#security-model)
  • [License](#license)

---

Why it exists

The harness's built-in @deepseek-ai/dsh-compaction-basic backend already compacts automatically, but its trigger is relative: a fraction of the current model's context window (thresholdRatio, default 0.8).

That is a great default, but some users want a policy that does not move when the routed model changes:

PolicyBuilt-inThis plugin
Trigger0.8 × model context windowexplicit token count, e.g. 262144
Defaultvaries with the model262144 (256K)
Scopeone compaction backend instanceprocess-wide, per-session backend resolution
Manual /compactstill availablestill available

When the absolute threshold is lower than the built-in ratio threshold, this plugin fires first. When it is higher, the built-in policy may fire first and this plugin re-measures and stays idle — both share the same engine, lock, and summary format, so they cannot double-compact the same span concurrently.

---

How it works

agent/pre-step (every session)
        │
        ▼
ctx.tokenMeter.measure(agent.session)
        │
        │  totalTokens < thresholdTokens ?
        ├── yes ──▶ do nothing, continue the step
        │
        ▼ no
resolve the agent's own compaction backend:
        serviceForAgent(ctx, agent, 'compaction')
        │
        ├── absent ──▶ one warning per agent, skip (preset has no /compact)
        │
        ▼ present
select the older, tool-pair-balanced surface span
(keep a recent tail worth at least retainTokens)
        │
        ▼
ctx.compaction.compactRegion(start, end, agent, signal)
        │
        ▼
re-measure; compact again if still above the threshold
(up to maxCompactions times per check)
        │
        ▼
continue the model step no matter what happened

Key points:

1. Measurement uses the platform's own ctx.tokenMeter, the same replay-aware estimator the built-in compaction backend consumes. totalTokens includes the latest durable request envelope plus the current conversation surface. 2. Range selection walks the token-priced surface from the tail, keeps a recent verbatim budget (retainTokens), and snaps the cut backwards until no unanswered assistant tool-call/tool-result pair is split. 3. Execution is the built-in ctx.compaction.compactRegion() call: the compaction backend records its durable compaction/startcompaction/end bracket, asks the model for a summary, and replaces the selected surface span with one user-role checkpoint. All lock, persistence, retry, and summary semantics belong to the harness, not to this plugin. 4. Failure handling is non-blocking. A failed or impossible compaction is logged and the model step continues unchanged; this plugin never vetoes a turn.

---

Coverage: every session, every preset

The plugin is installed on the host plane (a profile bundle), not inside a single agent preset:

  • It registers one agent/pre-step listener process-wide.
  • For every event it asks the agent itself for its compaction service

(serviceForAgent(ctx, agent, 'compaction')), so the correct per-preset, per-session isolated backend instance is used.

  • Consequently it works for:

- every agent preset that mounts a compaction backend (standard, code, cordis, local minimal-compact, anchored-standard, …); - fresh sessions, resumed sessions, and sessions loaded after a restart; - top-level agents and subagents.

Presets that intentionally mount no compaction backend (for example the shipped minimal preset, which has no /compact at all) are detected and skipped with a single warning per agent. There is nothing to compact with there.

---

Features

  • Absolute, user-configurable threshold — default 262144 tokens (256K).
  • Human-friendly values accepted: 262144, "256k", "256K", "1m".
  • Configurable verbatim tail (retainTokens, default 32768).
  • Configurable per-check retry cap (maxCompactions, default 3).
  • Configurable kill switch (enabled, default true).
  • Tool-call/tool-result aware cuts — never splits an open tool pairing.
  • Zero runtime npm dependencies; pure ESM host plugin.
  • All compaction work executes inside the harness's built-in backend.
  • Presets without a compaction backend (for example the shipped minimal

preset) get a plugin-owned compaction-basic fallback engine with auto: false, so the absolute-threshold check still works there. The preset stays otherwise minimal: no /compact command, no pruner, no built-in ratio pressure.

  • Idle/resume compaction (v0.2.2+): opening or resuming a conversation whose

context is already above the threshold compacts it through the built-in compactNow maintenance path — no follow-up message is required.

  • Idempotent installer and uninstaller.

---

Requirements

RequirementVersion / note
DeepSeek Harness0.1.0-rc.6 (web profile developed and verified against)
dsh on PATHlauncher for dsh plugin ...
pnpm on PATHused internally by dsh plugin
Node.js>= 20 (the plugin itself is dependency-free)
Preset compaction backendsessions should use a preset that mounts @deepseek-ai/dsh-compaction-basic

---

Installation

From a local checkout

git clone https://github.com/Zh-U-hB/dsh-auto-compact.git
cd dsh-auto-compact
./install.sh

Or, if the repository is already checked out:

cd /path/to/dsh-auto-compact
./install.sh

What install.sh does

1. Removes any rows a pre-1.0 prototype may have written into ~/.dsh/.agent-presets/*/agent.cordis.yml. 2. Runs:

``bash dsh plugin --profile web add /absolute/path/to/dsh-auto-compact ``

Because package.json declares dsh.bundle.patch, dsh plugin appends the bundle to the web profile and inserts the row:

``yaml - id: auto-compact name: dsh-auto-compact ``

Activate

Profile bundles are loaded when the process boots, so restart the web surface:

# Ctrl+C in the terminal running dsh web, then:
dsh web

Then hard-refresh the browser once (Cmd+Shift+R / Ctrl+Shift+R).

From that point on the policy is active for every session in the process, including sessions you resume afterwards.

Install into another profile

DSH_PROFILE=tui ./install.sh        # or any other profile name

For profiles without agent presets, the plugin still works as long as the profile composes a ctx.compaction backend and ctx.tokenMeter on the host plane (the standard dsh-base composition does).

---

Set the threshold in the web settings UI (v0.2.0+)

Open the harness settings gear, choose Plugins → Configurable, and use the Auto Compact card. The input accepts a plain token count (262144) or a human-unit value (256k, 1m; 1024-based). Saving writes the value through the platform settings service into the profile's settings.yaml, so it survives restarts and wins over the row config below. Discard resets the field back to the row config (or the 256K default).

The settings card itself is loaded as part of the plugin's client bundle, so after upgrading from an earlier version, restart dsh web once.

The row-level configuration below remains the base/default layer:

Configuration

Edit the profile's own patch layer:

~/.dsh/profiles/web/cordis.patch.yml

Default configuration (this block is optional — every key shown is the default):

- id: auto-compact
  config:
    thresholdTokens: 262144   # 256 × 1024; "256k" / "1m" also accepted
    retainTokens: 32768       # minimum recent tail kept verbatim
    maxCompactions: 3         # maximum consecutive compactions per check
    enabled: true             # false pauses the plugin without uninstalling

Examples:

# Compact earlier: at 128K tokens.
- id: auto-compact
  config:
    thresholdTokens: 131072
# Use human units and keep a larger tail.
- id: auto-compact
  config:
    thresholdTokens: 256k
    retainTokens: 64k
# Pause without uninstalling.
- id: auto-compact
  config:
    enabled: false

Restart dsh web after changing the profile patch.

Validation rules

  • thresholdTokens and retainTokens must be positive integers (or

human-unit strings that resolve to one).

  • retainTokens < thresholdTokens.
  • maxCompactions must be a positive integer.
  • Unknown config keys fail plugin load with a descriptive error, so a typo

cannot silently fall back to defaults.

---

Behavior and semantics

tokenMeter replay fallback

If the platform's replay-aware ctx.tokenMeter.measure() throws for a session (for example, a log interrupted across a step boundary is missing a matching step/start), the plugin temporarily wraps the tokenMeter instance and falls back to a surface-plus-request-envelope token estimate (the same fixed-density heuristic the token meter uses) for compaction decisions. The warning dsh-auto-compact: tokenMeter replay failed (...) is logged once per session. This keeps compaction working on damaged-but-usable sessions; healthy sessions never use the fallback.

The same absolute threshold is also checked on agent/created while the agent is idle, so a resumed session that was already over the threshold is compacted as soon as it is opened. compactNow runs as an agent maintenance job (the same path as the built-in /compact command); if a turn has already started, the pre-step check handles it instead.

When the check runs

The check runs on the agent/pre-step waterfall — immediately before the model request for a step is assembled. Because compaction then runs inside the open turn, the compaction backend's automatic path is used, which is the same mechanism the built-in ratio policy uses.

What "context reached the threshold" means

ctx.tokenMeter.measure(session).totalTokens is used. It is the harness's own replay-aware estimate of the latest durable request envelope plus the current conversation surface. It is an estimate, not a provider-exact token count, and it is deliberately the same number the built-in compaction backend compares against.

What happens when compaction is impossible

  • No safe cut exists (for example, the tail is one huge unfinished tool unit):

one warning is logged per session until the condition clears.

  • The threshold is reached but the backend refuses (busy, changed,

summary, commit, persistence, …): the error is logged and the step continues.

  • The threshold is still exceeded after maxCompactions attempts: the plugin

logs a warning and continues the turn. A single oversized indivisible node cannot be repaired by surface compaction — the same limitation the built-in backend documents.

Relationship with the built-in /compact command

/compact keeps working exactly as before. The manual command compacts one useful balanced span below pressure thresholds on an idle agent; this plugin compacts at step boundaries when the absolute threshold is crossed. Both use the same ctx.compaction implementation and therefore the same durable lock, so concurrent or nested runs are impossible.

Threshold policy and model changes

Because the threshold is absolute, switching the routed model does not change when this plugin fires. The built-in ratio policy still runs alongside it and may fire earlier for models with a small context window; that is intentional and safe.

---

Logging

All messages are prefixed with dsh-auto-compact: and use the harness logger:

LevelMessage patternMeaning
infocontext at N tokens reached the ... thresholda compaction attempt starts
infoidle context at N tokens reached the ... thresholdan idle/resumed session compacts without a new message
infoidle compaction shadowed ...an idle compaction completed
infocompacted N history items (~N tokens shadowed)an attempt succeeded
warnno tool-pair-balanced older span is compactablethreshold exceeded, nothing safe to compact (rate-limited per session)
warncontext is still at N tokens after N compaction attempt(s)retry cap exhausted (rate-limited per session)
warnagent "..." has no ctx.compaction service and no fallback engine could be mountedbackend unavailable; the turn continues (once per agent)
warnautomatic compaction failed (...)backend error; the turn continues

---

Uninstallation

./uninstall.sh

The script runs:

dsh plugin --profile web remove dsh-auto-compact

and also removes any legacy preset-local rows. Restart dsh web afterwards.

---

Local development and tests

No package installation is required for development: the runtime plugin has no dependencies.

npm test        # node --test unit + integration-style apply tests
npm run check   # syntax-check plugin and scripts, then run tests

Test coverage:

  • config parsing/validation (defaults, 128k/1m, rejections);
  • balanced-cut folding around open tool pairings;
  • surface-span selection against token-meter measurements;
  • apply() behavior: threshold reached, below threshold, backend throwing,

missing backend (warning once per agent);

  • the settings namespace updating the runtime threshold;
  • the client settings-card bundle registration.

A test/mount-smoke.mjs helper is included for one-shot headless checks that a preset composition mounts and exposes ctx.compaction without making any model request.

---

Repository layout

dsh-auto-compact/
├── lib/
│   ├── index.js              # host plugin: threshold enforcement + settings namespace
│   └── client.js             # web settings card (Plugins → Configurable)
├── scripts/
│   └── manage-presets.mjs    # legacy preset-row cleanup helper
├── test/
│   ├── unit.test.mjs         # config + range-selection unit tests
│   ├── apply.test.mjs        # apply() + settings integration tests
│   ├── client.test.mjs       # client bundle registration smoke test
│   └── mount-smoke.mjs       # headless preset-mount smoke helper
├── cordis.patch.yml          # bundle patch: inserts the auto-compact row
├── install.sh                # dsh plugin add wrapper
├── uninstall.sh              # dsh plugin remove wrapper
├── package.json              # package + dsh.bundle.patch + dsh.client metadata
└── README.md / README.zh.md

---

Compatibility

Developed and verified against DeepSeek Harness 0.1.0-rc.6 (web profile). The plugin depends on stable harness seams (ctx.tokenMeter, agent/pre-step, agent.ctx, ctx.compaction.compactRegion) but these are developer-preview internals: after a harness upgrade, re-run the test suite and start a fresh session before relying on the plugin.

The installer works with the standard dsh plugin command and keeps the plugin as a linked local package, so edits to your checkout are visible after the next dsh web restart.

---

Troubleshooting

The plugin row is in dsh --profile web --dump-config, but nothing happens

The process must be restarted. Host-plane bundles are loaded at boot; editing the profile on disk is not hot-reloaded into a running dsh web.

A session never compacts

  • Check enabled is not false.
  • Check the session's preset actually mounts

@deepseek-ai/dsh-compaction-basic; the shipped minimal preset does not.

  • Check the harness log for the dsh-auto-compact: messages above.
  • Remember the threshold counts the whole measured request envelope plus

surface; a mostly-tool-call session can take longer to cross it than the raw transcript size suggests.

A preset shows "has no ctx.compaction service and no fallback engine could be mounted"

Since v0.2.1 the plugin mounts a compaction-basic fallback engine into presets that have none (including the shipped minimal preset). The warning above now only appears when that fallback could not be constructed — for example in a profile that also lacks @deepseek-ai/dsh-compaction-basic or @deepseek-ai/dsh-llm on the host plane.

I edited cordis.patch.yml and nothing changed

Profile patch changes also require a dsh web restart.

---

Security model

  • The plugin registers no HTTP endpoints, tools, commands, or settings writers.
  • It only reads ctx.tokenMeter and invokes the existing ctx.compaction

service that the session's preset already trusts.

  • It never constructs file paths, performs I/O, or handles user input beyond

validating its own YAML config.

  • Every mutation of conversation history is performed by the harness's built-in

compaction backend under its existing sandbox/durability rules.

---

License

[MIT](./LICENSE)