DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

Session Rescue — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
S

dsh-session-rescue

Session Rescue

防止 DeepSeek Harness 冷启动回合卡住:重启或加载会话后,首个回合可能会因令牌计量器同步重放整个会话日志而永久阻塞;此插件会在会话大小达到该危险范围前压缩会话,使重放保持低开销。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:1622352030/dsh-session-rescue#b63803b3ddc1f855e34acc04b06c5b1057f41bd8
README兼容性版本

兼容性与来源证明

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

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

版本

0.2.0stable
2026/9/24
0.1.0stable
2026/9/24

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题

相关插件

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

Archive Manager@michengai/dsh-archive-manager可通过 NPM 安装的 DSH Web 插件,用于管理已归档的会话。Memsearch Dsh@zilliz/memsearch-dsh适用于 DeepSeek Harness 的 MemSearch 插件:在多个代理之间共享 Markdown 记忆,支持捕获、步骤前上下文注入、记忆召回技能和技能候选审核面板。Rewind Plugindsh-rewind-plugin同窗口内对话回退并恢复工作区文件MisakanetmisakanetMisakaNet 失败记忆技能——为 AI 代理提供按证据评级的失败经验。DSH bundle:将 MCP 工具注册为 mcp__misakanet__*(misakanet_search/get_lesson/…),由公共 Streamable HTTP 端点 https://misakanet.org/mcp 提供服务——实时工具 f

README

dsh-session-rescue

Status: v0.2.0 — prevention, not detection. The stall was traced to a specific window and a specific code path (below), and the plugin logic is covered by 55 tests (55 pass / 0 fail). The plugin has been loaded and exercised in an isolated DSH_HOME, never against the running instance. Be careful reading the mechanism below: the code-level facts are verified, the causal link from the replay to the stall is NOT — there is counter-evidence, stated in docs/DESIGN.md → Open questions. The stall has not been reproduced under control, and the cold first turn's cost has not been attributed to a specific listener yet.

A DeepSeek Harness plugin that stops the cold-start turn stall: after a restart or a session load, the first turn can block forever with the UI spinning and nothing in the log. This plugin prevents that by compacting the session before its size reaches the zone where the stall becomes fatal.

The problem, precisely

⚠️ Read this first: the causal claim below was FALSIFIED by direct measurement. The code-level facts in the table are verified, but they are not the cause of the stall. tools/measure-replay.js runs the product's own TokenMeter._sync over a reconstruction of the real session and the entire 526,383-seq cold replay costs 47 ms — against a cold first turn measured at 16,008 ms and turns that never returned. The replay is ~340× too small. The cause is still unknown; what remains true is that cold first turns are far slower than warm ones, it grows with session size, and /compact was the only observed recovery. See docs/DESIGN.md → Measured falsification.

A stalled session log looks like this, with no error anywhere:

agent/inbox/spliced     ← the user message is accepted
turn/start              ← the turn is opened
                        ← and then nothing, forever: no step/start, no assistant frames

The silence sits exactly in the preStep window, between turn/start and step/start. The cause is not a missing timeout and not the network — it is a synchronous full replay of the whole session log that runs inside that window:

StepEvidence
A restart or session load creates a new Session object@deepseek-ai/dsh-session/lib/index.js:1322 appends session/end-seed on load
The token meter's replay state is a WeakMap<Session, state>@deepseek-ai/dsh-token-meter/lib/index.js:589
A new object ⇒ empty state ⇒ replay from 0dsh-token-meter/lib/index.js:679-697, while (state.consumedEvents < session.seq)
Something calls it on every pre-stepdsh-compaction-basic/lib/index.js:782 (agent/pre-step) → :862 meter.measure(session)
So the replay runs between turn/start and step/startdsh-agent-loop/lib/index.js:528 → :539 → :553

That loop is synchronous: it blocks the event loop, so step/start can never be written and while (await this.turn()) never returns. The UI spins forever.

Measured on one real session (session-db08f763, 5.9 MB, seq space ≈ 517 k):

Turnseq at startcold or warmpreStep duration
235,236warm (same process)231 ms
545,585cold (process just restarted)16,008 ms
7 / 28–30 / 34–3593 k / 389 k / 446 kcoldnever returned (user gave up after 20–47 s)
8 / 31 / 36same sizes, after /compactcold1.6 s / 10.1 s / 4.7 s ✅

Three properties follow from this, all confirmed against the real logs:

  • Restarting does not help — it makes it worse. Every restart is another cold replay of an ever-longer log.
  • /compact does help — it was the only thing that ever recovered these sessions.
  • Size alone is not the trigger — a turn at 232,878 tokens succeeded warm while one at the same size failed cold. When the replay happens is what decides the outcome.

How the plugin fixes it

Honest framing, given the falsification above: the plugin does not absorb the mystery cost. compactNow begins with measure(), which is cheap (47 ms for the whole session), so compacting at load does not pay whatever the slow listener charges. What the plugin actually delivers is the automation of the one operation observed to restore service — proactive compaction, at load when a session is already large and between turns as it grows. If the slow listener scales with the visible surface, keeping the surface small helps; that is a hypothesis, not a result.

The replay is unavoidable — but where you pay for it is not. Paid inside the user's first turn it is a permanent hang; paid while the agent sits idle after a load it is just a slow start. And once compaction has run, the following cold starts stay cheap.

  1. GUARD — when a session is loaded into this process and its seq is already past the danger threshold, compact it before the user's first turn (agent/status → idle). This moves the unavoidable cost out of the turn and shrinks the surface at the same time.
  2. COMPACT — between turns, while the agent is idle, compact whenever the session has grown by a configured amount. This keeps future cold starts in the seconds range.
  3. Report — /rescue status shows the per-session seq, whether this process has already paid the replay ("warm") or not ("cold"), and the plugin's own measurement of the preStep window (turn/start → first step/start) for both cold and warm turns.

Only one API is used to act: the official compaction seam, ctx.compaction.compactNow(agent, signal, commandId) (@deepseek-ai/dsh-command-compact/lib/index.js:8,54). The service is fetched with ctx.get('compaction') rather than injected, so the plugin still loads and reports in compositions that have no compaction.

Anti-thrash (why the trigger is a growth delta)

Compaction does not shrink session.seq — the log is append-only and compaction appends its own records. A plain "compact when seq >= threshold" rule would therefore re-fire on every idle forever. The trigger is instead "grown by at least minGrowthSeq since the last compaction", and a successful compaction pushes that baseline to the current seq. Both are property-tested in test/guard.test.js.

busy is also treated specially: it means the core refused the call because a compaction is already running or the agent is not idle. No replay was paid, so the plugin does not mark that session warm (otherwise the cold session would miss its GUARD and the next user turn would hang again). Retries are throttled by a cooldown and a consecutive-busy cap.

Configuration

- insert:
    - id: session-rescue
      name: dsh-session-rescue
      config:
        enabled: true        # false = observe and report only, never compact
        warnSeq: 40000       # start warning/compacting from here
        dangerSeq: 80000     # cold first turn may never return past here
        minGrowthSeq: 20000  # compact only after this much growth since the last compaction
        cooldownMs: 60000
        maxAttemptsPerSession: 6
        maxBusyStreak: 5
        pollMs: 30000
        compactionTimeoutMs: 600000

The default thresholds are calibrated from the table above (40 k is where a cold first turn is already ~16 s; 80 k is inside the "never returned" range). They are machine- and session-dependent — measure your own with /rescue status and adjust.

What is in the repository

PathWhat it is
src/host.jsHost plugin entry: session/event + agent/status wiring, GUARD/COMPACT execution, /rescue.
src/guard.jsPure decision state machine — when to guard, when to compact, cooldown, caps, busy handling.
src/size.jsSize metric and thresholds for the danger zone, with the calibration data in comments.
src/detect.jsOffline only. Stall-signature detector over session events (used by the replay tool).
src/frames.jsOffline only. Read-only session-log analysis: per-frame zstd decode, synthetic-closer detection.
bin/dsh-session-rescue.mjsRead-only scan CLI — usable without installing the plugin.
tools/replay.jsReplays a real session log through the detector to check hit/miss rates.
tools/measure-replay.jsRuns the product's own TokenMeter._sync over a reconstruction of a real session log — the measurement that falsified the replay hypothesis (47 ms for 526,383 seqs).
test/*.test.js55 unit and integration tests (node --test), run against a fake cordis context.
tools/Install-Plugin.ps1Idempotent install / rollback for a DSH profile — dry-run by default, snapshot-based.
docs/DESIGN.mdDesign notes: the mechanism with source citations, the fix, bounds and open questions.

Limitations stated up front

  • Verified in an isolated DSH_HOME, not end-to-end against the stall. A real headless Harness run loaded the plugin, fired its agent/status hook, resolved ctx.get('compaction'), and opened a real compaction transaction (compaction/start carrying sourceCommandId: "session-rescue-guard-1") — reproduced twice. The stall itself was not reproduced, and the "compact before the first turn" ordering is covered by unit tests only. See docs/DESIGN.md → Verification performed.
  • The size threshold is a proxy. What actually costs time is the replay's per-event work, which cannot be measured from outside without paying for it. seq is the driver of the loop and is free to read, so it is used as the proxy — calibrated, not derived.
  • One link is unproven. Compaction demonstrably made the next cold start cheap in all three observed episodes (never-returning → 1.6–10 s), but why is not established: it cannot be by shortening the replay, since seq does not shrink. The plugin relies on the measured effect, and docs/DESIGN.md records the question as open.
  • Compaction costs an LLM call (15–20 s on the observed 300 k-token sessions) and rewrites history into a summary. That is a real change to your conversation, by design — the same operation /compact performs. Set enabled: false for report-only mode.
  • The earlier v0.1 approach (detect a stalled turn → cancel → cold rebuild) has been removed: the stall is a synchronous CPU loop, so signal.throwIfAborted() never gets a chance to run and cancellation cannot interrupt it.

Read-only scan CLI (no install required)

node bin/dsh-session-rescue.mjs scan --stalled-only     # sessions that stalled or have an unclosed turn
node bin/dsh-session-rescue.mjs scan --all --json       # every workspace bucket, machine readable

It reads session logs (read-only, tail window only, never prints message bodies).

Development

node --test test/size.test.js test/guard.test.js test/host.test.js
node --test test/detect.test.js test/frames.test.js   # offline forensics

Compatibility

Developed against DSH Desktop 0.8.2 with @deepseek-ai/dsh@0.1.2-rc.1 — every line reference above was read from that installed build.

License

MIT