DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Idle Compactor — DeepSeek Harness 插件(DSH Plugin)
← Plugins
I

dsh-idle-compactor

Idle Compactor

由空闲状态触发的 DeepSeek Harness 上下文压缩:会话静默时间超过令牌下限后压缩会话

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:QuanhuZeYu/dsh-idle-compactor#60195e2e20e850807d21f5e62da848f8fed25751
README兼容性版本

兼容性与来源证明

Idle Compactor 以 dsh-idle-compactor 发布,当前版本为 0.2.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
any
发布来源
github
Registry 更新时间
2026/9/4

版本

0.2.0stable
2026/9/4
0.1.0stable
2026/9/4

相关插件

正在加载相关插件…

最新版
0.2.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/4
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

相关插件

继续浏览 memory-context 分类下经过校验的插件。

Memory Plugin@openviking/dsh-memory-plugin适用于 DeepSeek Harness 的 OpenViking 记忆与上下文套件Contextdsh-context用于上下文洞察和管理的 DeepSeek Harness 插件,提供上下文仪表板和上下文命令,帮助了解上下文的构成及其演变过程。Weknora@wxg-prc-cpg/dsh-weknora适用于 DeepSeek Harness (dsh) 的 WeKnora 知识检索工具:通过自有知识库进行语义搜索、文档阅读以及 RAG/代理回答。Memsearch Dsh@zilliz/memsearch-dsh适用于 DeepSeek Harness 的 MemSearch 插件:在多个代理之间共享 Markdown 记忆,支持捕获、步骤前上下文注入、记忆召回技能和技能候选审核面板。

README

dsh-idle-compactor

English | 简体中文

Idle-triggered context compaction for DeepSeek Harness.

A session that has grown past a token floor and then gone quiet gets compacted on its own, so you come back to a condensed history instead of paying for the stale tail on every request.

Built-in automatic compaction knows two triggers only: request pressure, and a provider-confirmed context overflow. It never asks how long a session has sat unused. This plugin adds that axis — idle time and context size, and both must clear their floor before anything happens.

Requirements

  • DeepSeek Harness with the compaction seam and tokenMeter (verified against 0.1.2-alpha.3).
  • No runtime dependencies. Every @deepseek-ai/* import in the source is import type and is erased, so lib/index.js is a single self-contained ESM file.

Install

git clone https://github.com/QuanhuZeYu/dsh-idle-compactor.git
dsh plugin --profile web add ./dsh-idle-compactor

# pnpm 9 refuses to add a dependency to a workspace root without the flag:
dsh plugin --profile web add -w ./dsh-idle-compactor

Then restart the profile: a patch layer reloads live, bundle mounting does not.

The bundle carries its committed lib/ output, so a git or path install needs no build script and no allowBuilds allowance. dsh plugin add is what appends the bundle to the profile layer stack, which makes its cordis.patch.yml take effect. Doing it by hand means writing the same two things into ~/.dsh/profiles/web/package.json:

{
  "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-idle-compactor"] } },
  "dependencies": { "dsh-idle-compactor": "link:../../dsh-idle-compactor" }
}

What it does

Every sweep (default: every 30 s) walks the live agents in this process and compacts the ones that clear all of these bars:

BarWhere it comes from
The agent is idle — no driver, no maintenance taskagent.status
Its newest session-log event is older than idleMssession.events.at(-1).time (durable, so a restart cannot fake a fresh session out of compaction)
Its measured request pressure is at least thresholdTokensctx.tokenMeter.measure(session).totalTokens
Its model-visible surface is at least thresholdTokens too.surfaceTokens from the same measurement
Nothing new has landed since the last checkpointper-session compactedAt watermark
Its cooldown or failure backoff has elapsedcooldownMs, retryBackoffMs
It is not archivedctx.workspaceRegistry.archivedSessionIds
It is not waiting on background workits own outstanding ctx.jobs, its inbox, and the live sessions it parents

Archiving a session hides it from every grouping surface and deliberately leaves a live agent running, so the sweep names archived ids explicitly: hiding a conversation is not a request to rewrite what it shows the model. A session whose archive set is still loading is skipped too — nothing is compacted on an unclassified session.

Why pressure and surface are both required

totalTokens is request pressure: an anchor carrying the previous successful call's provider usage, repriced only by the next call. surfaceTokens is the content compaction actually shrinks. A session compacted moments ago therefore reads high pressure over a small surface — re-summarizing it would spend detail to reclaim nothing — so both halves must clear the floor before a sweep acts. Those skips are logged at debug level.

This is also why the context figure in the UI can stay high after a compaction you can see in the log: the number is the pressure anchor, and the next request is what reprices it.

Compaction runs through the standard seam ctx.compaction.compactNow(agent, signal) — the same entry point /compact uses: an idle-session maintenance transaction with the backend's own range selection and retention policy. The plugin picks no range and writes no summary.

Why quiet is not the same as finished

A parent that ends its turn while a background child is still working is idle by the loop's own measure, and that wait is bounded by the child rather than by idleMs: a delegated run can take ten minutes or three hours. Condensing the parent's history mid-wait would rewrite the context the settlement is about to return to, so the sweep consults three further ledgers:

  • the session's own outstanding jobs — ctx.jobs.list(agent), kept down to the snapshots this session owns, which is also why a long background pwsh build holds its session;
  • the session's inbox, which carries a notice that has landed but not yet opened a turn;
  • the live sessions this one parents, directly or transitively.

The third ledger is not redundant with the first. The harness registers no job for a continuable child or for a child woken by send_message, and a child driver still reports idle in the window between accepting a prompt and starting its turn — so a descendant that logged anything inside the quiet window counts as work in flight, including one still inside its creation window. A child that has gone quiet for idleMs stops holding the parent, and a child that is not resident in this process never held it: there is nothing left to wake the parent for.

waitWarnMs reports a long wait instead of cutting it short: once an episode crosses it, the sweep logs one warning for that episode and keeps waiting.

Why the bundle also enables a host-plane backend

An agent preset mounts compaction-basic inside an isolate realm, and dsh-web-app disables the host copy, so a host fiber cannot read the realm instance. The bundle patch therefore re-enables the host row with auto: false: it answers idle compactNow() requests and registers no pressure compaction of its own, leaving the preset backend as the one that reacts to request pressure. A side effect users of the minimal preset will appreciate: those sessions have no compaction backend at all otherwise, and now they can be compacted too.

Configuration

Set it in the profile's cordis.patch.yml (later layers win, and a patch replaces the whole config, so restate every key you keep):

- id: idle-compactor
  config:
    thresholdTokens: 131072   # 128K
    idleMs: 600000            # 10 minutes
KeyDefaultMeaning
enabledtrueRegister no sweep at all when false.
thresholdTokens131072Context floor. Use 128000 for a decimal 128K.
idleMs600000Quiet window before a session is eligible.
scanMs30000Sweep interval; bounds how long after idleMs the compaction lands.
includeSubagentsfalseAlso compact sessions whose header carries origin: subagent.
excludeArchivedtrueSkip sessions the workspace registry reports as archived.
skipAwaitingWorktrueNever compact a session with background work outstanding — its own or a live descendant's.
waitWarnMs10800000Log one warning per wait episode once it has held a session this long.
cooldownMs60000Minimum spacing between compactions of one session.
retryBackoffMs300000Wait after a failed attempt or a "no compactable range" result.
maxPerScan1Sessions per sweep, bounding concurrent summarization calls.
dryRunfalseLog what would be compacted; write nothing.

Unknown keys and out-of-range values throw at load.

Model experience

  • One summarization request per landed compaction, made by the compaction backend on the session's routed model. No extra request per turn, no injected notice, no prompt section.
  • The only model-visible result is the checkpoint node that replaces the compacted range.
  • A session below thresholdTokens is measured once and then re-armed for the next interval instead of being re-measured on every tick.

What compaction does not do

The durable log is never rewritten. A compaction appends compaction/start, compaction/summary, and compaction/end, then lands one user/message carrying surfaceOp: replace over the selected span; shadowedSeqs names every event it moved out of the model-visible surface, so the original text stays in the session log and a consumer can read it back. Neither the storage index nor the archive flag changes.

Known limitations and deferred work

  • Live agents only. A session with no agent in this process has no surface to measure and no agent to run maintenance against, so closed or never-opened sessions wait until they are opened. A cold path would have to resume an agent per candidate; that is also why includeSubagents defaults to false — background children are already owned by their parent lifecycle.
  • A running turn is never interrupted. Eligibility requires agent.status === "idle", and compactNow is a between-turn maintenance task; a session whose turn has been running for hours is not idle in either sense. Its between-turn twin — quiet while a child works — is held by skipAwaitingWork, so a parent whose wait is unbounded is compacted only after that wait ends.
  • No settings panel. Configuration lives in the patch layer; a settings.section with hot reload is the natural follow-up.

Development

npm install                              # typescript + vitest as dev dependencies
npm run link-dsh -- <path-to-dsh-checkout>   # resolve the harness packages from a checkout
npm run build                            # src/index.ts -> lib/index.js
npm test                                 # 12 integration tests
npm run typecheck:tests                  # typecheck the specs too (tsconfig.check.json)

Most @deepseek-ai/* packages the source is typed against are not on the public registry, so scripts/link-checkout.mjs links a local DeepSeek Harness checkout into this project's own (gitignored) node_modules. It writes nothing into that checkout, and when several checkouts sit side by side it refuses to guess — pass the one you mean. npm install is optional: without it the script borrows the checkout's own typescript and vitest, and the npm scripts call those by file, not by bin shim, so a borrowed copy works exactly like an installed one.

tests/idle-compactor.spec.ts composes a real agent loop, a real session log, a real token meter and a real BasicCompactionEngine (only its summarizer is scripted), and asserts the durable compaction/summary events the run leaves behind rather than mock call counts. It exercises the built bundle by default — the same artifact the profile loads; point DSH_IDLE_COMPACTOR_BUNDLE elsewhere to check a different build.

Covers: an over-threshold idle session lands exactly one compaction and its measured context shrinks; a second quiet window with no new activity does not repeat it; fresh activity re-arms it; a below-threshold session is untouched; a surface already under the floor is left alone while pressure reads over it; an archived session is untouched, including while the archive set is still loading; dryRun writes nothing; bad configuration throws. Waiting is covered from both sides: a session holding an outstanding job and a session whose child is mid-turn are left alone and then compacted once the wait ends, while an unrelated mid-turn session or a job owned by someone else compacts on schedule.

Layout

src/index.ts              the plugin (type-only imports, zero runtime dependencies)
lib/                      committed build output - what the profile loads
cordis.patch.yml          the bundle layer: the plugin row plus the host-plane backend
tests/                    integration tests against a composed harness
scripts/link-checkout.mjs dev-only: resolve harness packages from a checkout, read-only
vitest.config.mjs         standalone test root; no harness checkout config involved
tsconfig.json             erasable-syntax-only ESM, declarations into lib/types
tsconfig.check.json       test-plane typecheck: src plus specs, with Node ambient types

License

MIT — see LICENSE.