DeepSeek Harness plugin

dsh-compact-after-task

Auto-compact a DSH conversation after the current task finishes, at a user-set context threshold.

Jump to install

Source facts

Repository
xiaoliang2/dsh-compact-after-task
Latest update
Aug 21, 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/xiaoliang2/dsh-compact-after-task
Plugin: dsh-compact-after-task
Author: xiaoliang2

Check the source files

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

File explorer3 files
README.mdSource · read only

dsh-compact-after-task

A DSH (Cordis) plugin that auto-compacts a conversation after the current task finishes, whenever context pressure crosses a threshold you set (default 50% of the routed model's context window). Install it and stop manually clicking "compress" — and stop letting the context (and the bill) grow unchecked. <img width="1188" height="978" alt="图片" src="https://github.com/user-attachments/assets/8bad7d73-2913-4589-80a6-51857e10a177" />

The switch and the threshold are adjustable directly in Settings → Plugins (toggle + slider); changes apply immediately, no restart needed.

The problem it solves

In a long conversation the model re-receives the entire history on every turn. As the conversation grows, this bites harder and harder:

  • No compaction → exploding cost. The bigger the context, the more tokens each turn re-sends. Even with a provider KV cache (cheaper than fresh input, still not free), the history is re-transmitted and re-billed every single turn. Rolling from tens of thousands to hundreds of thousands of tokens quietly multiplies per-turn cost — the longer you talk, the more each reply costs, without you noticing.
  • Manual compaction is tedious and easy to forget. /compact or the UI compress button works, but you have to remember to use it — and people only remember once things are already slow and expensive, after several huge turns have been paid for.
  • The built-in auto-compaction is a late, mid-task safety net. dsh-compaction-basic only fires at 80% of the context window, and only at a step boundary while a task is running — by then you've already paid for several enormous requests, and the compaction interrupts work in progress.
  • Slower responses. Longer prefixes mean more processing per request and a noticeably sluggish feel.

This plugin automates the "remember to compress" chore: after each task finishes (the agent returns to idle) it checks the pressure and compacts at your chosen threshold — dealing with cost before it hurts, not after.

How it relates to the built-in compaction (complementary, not a replacement)

Built-in dsh-compaction-basicThis plugin
WhenAt each step boundary (agent/pre-step), mid-taskAfter the task fully finishes (agent returns to idle)
ThresholdthresholdRatio 0.8 (fixed)thresholdRatio user-set, default 0.5
RoleLast-resort mid-task safety netRoutine "slim down between tasks"

The compaction itself is identical to /compact: it calls ctx.compaction.compactNow(), produces one <compacted-summary> checkpoint, and the conversation UI shows the usual "compacted N history items" card.

Requirements

  • DSH Desktop / DSH profile with the base bundle (dsh-base), which provides dsh-compaction-basic, dsh-token-meter, dsh-agent and dsh-llm.
  • Core auto-compaction works on any version. The settings-page card (toggle + slider) needs DSH ≥ 0.1.0-rc.7 (released 2026-08-17): since rc.7 the Host serves every registered settings namespace to the browser automatically, so a third-party plugin's settings card works out of the box — this is the official mechanism. On rc.6 and earlier the namespace list was hardcoded and a third-party namespace was refused (settings-not-exposed) — upgrade, or apply the two-line patch below only if you cannot upgrade.
  • On rc.7+ this plugin reaches the compaction service via agentPresets.serviceFor(), not inject: ["compaction"]. Since rc.7 introduced agent presets, the compaction service is no longer provided on the host plane — each session's preset (standard/cordis/…) mounts it inside an isolate realm, so a host-plane plugin that injects compaction pends forever (waiting for service: compaction). This plugin instead calls the official read API ctx.agentPresets.serviceFor(agent, "compaction") when the agent goes idle (that API exists precisely for callers whose request is about a session but arrives from outside it); on rc.6 and earlier it falls back to ctx.get("compaction").
  • For the settings card to appear, the package exports must expose "./package.json": "./package.json". dsh-client-modules discovers client bundles by resolving <package>/package.json to read the dsh.client metadata; if a package declares exports without that key, the lookup throws ERR_PACKAGE_PATH_NOT_EXPORTED and the package is silently cached as "not a client package" — the host half runs fine but the settings card never shows. All official packages ship this line in exports.

Install

Two ways — pick one (do not mix them: the loader rejects a duplicate entry id).

A. Standard: plugin market / dsh plugin add (recommended)

The package ships a dsh.bundle.patch pointing at its own cordis.patch.yml, so it is a first-class bundle: installing it via the market or the CLI adds it to the profile's dsh.profile.bundles, and on the next boot the loader applies the package's own patch layer automatically — no manual editing needed.

# from npm (after publishing) — or from GitHub directly:
dsh plugin --profile desktop add @xiaobanli/dsh-compact-after-task
dsh plugin --profile desktop add github:xiaoliang2/dsh-compact-after-task

Or, in the desktop app, open Settings → Plugin Market and one-click install. Restart DSH Desktop, done.

B. Manual, profile-local (no market, no publishing)

1. Copy this package into the profile and make it resolvable from the profile's node_modules (same way dshmarket is installed):

``powershell # from the DSH home, e.g. C:\Users\you\.dsh\profiles\desktop Copy-Item -Recurse <path-to>\dsh-compact-after-task .\plugins\dsh-compact-after-task New-Item -ItemType Junction -Path .\node_modules\@xiaobanli\dsh-compact-after-task -Target .\plugins\dsh-compact-after-task ``

2. Add the plugin row to the profile's cordis.patch.yml (your user patch layer, applied after every bundle layer):

``yaml - insert: - id: compact-after-task name: '@xiaobanli/dsh-compact-after-task' config: enabled: true thresholdRatio: 0.5 ``

3. Declare the dependency in the profile's package.json so a later pnpm install does not prune it:

``json "dependencies": { "@xiaobanli/dsh-compact-after-task": "file:plugins/dsh-compact-after-task" } ``

4. Restart DSH Desktop for the profile change to take effect.

> If you already installed it manually (method B), uninstall/remove it before installing via the market, otherwise the same entry id compact-after-task is inserted twice and the loader refuses to boot.

Only on DSH ≤ 0.1.0-rc.6 (if you cannot upgrade)

Before rc.7 the Host exposed only a hardcoded namespace whitelist, so the settings card cannot read/write until you add this plugin's namespace to it (two files in the app install, under resources\app.asar.unpacked\node_modules\@deepseek-ai\dsh-host-apiproxy):

  • lib/index.js — in const WEB_SETTINGS_NAMESPACES = [ ... ] (~line 888) add "compact-after-task",
  • lib/types/api-proxy.js — in the single-line const WEB_SETTINGS_NAMESPACES = [...] (~line 50) add "compact-after-task"

Then restart. Note DSH updates overwrite these files, so re-apply after each update. On rc.7+ this patch is unnecessary and these files no longer exist.

Configuration

KeyTypeDefaultMeaning
enabledbooleantrueMaster switch.
thresholdRationumber (0.05–1)0.5Compress when pressure reaches this fraction of the routed model's context window (0.5 = 50%).
onlyRootsbooleanfalseOnly compress top-level conversation agents (skip background subagents).

Adjust from the settings page (toggle + slider)

After install, an Auto-compact card appears under Settings → Plugins → Configurable plugins:

  • Toggle: auto-compact after each task finishes;
  • Slider: auto-compact threshold (5%–100%, 5% steps).

Releasing the slider saves immediately; the settings/updated event applies it live, no restart needed. The value persists in the settings document and takes precedence over the loader config in cordis.patch.yml (which acts as the default/base layer).

Picking a threshold

Set it from "the max per-turn re-send you can tolerate ÷ the model's context window":

  • DeepSeek's default 1M window: 0.3–0.6 is the sweet spot; 0.5 is a conservative default.
  • Want each turn to re-send ≤ 400K tokens → 0.4; ≤ 250K → 0.25.
  • Don't go ≥ 0.8: the built-in compaction already fires at 0.8 at a step boundary, so a higher threshold here is meaningless.
  • Small-window models (128K/64K): raise to 0.6–0.8, or you'll squeeze out useful working context.
  • Too low (below ~0.1) means compressing after every small task, and the summary swallows details that were still useful.

Tune by feel after a couple of long tasks: compressing after every little task / summaries getting coarse → raise it; still re-sending hundreds of thousands of tokens per turn → lower it. Edit thresholdRatio in cordis.patch.yml and restart.

Behavior details

  • Listens to the agent/status event and acts only on the idle transition — i.e. the current task's drive has fully drained. This is the "compress after finishing the current task" moment; it never interrupts a running task.
  • Uses the same pressure measurement as the built-in engine: tokenMeter.measure(session).totalTokens vs contextWindow × thresholdRatio (context window resolved via llm.resolveModelInfo).
  • Compaction is a single ctx.compaction.compactNow(agent, signal) call — the same operation /compact runs; compactNow reserves next-turn admission, so queued messages are correctly deferred until the compaction finishes. On rc.7+ ctx.compaction is the instance returned by agentPresets.serviceFor(agent, "compaction"); the operation is unchanged.
  • Expected failures are silent: busy (agent busy / a compaction already running) and cancelled are skipped; anything else is logged as a warning without disturbing agent lifecycle events.
  • If the agent's preset mounts no compaction group (e.g. minimal), serviceFor returns undefined and that agent is skipped.

Test

npm install
node test-compact-after-task.mjs

The unit test stubs the services and covers: idle + above threshold compacts, below threshold does not, running does not, busy is silent, disabled does nothing, onlyRoots filters subagents.

License

[MIT](LICENSE)