DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
C

dsh-context-keeper

Context Keeper

教会 DeepSeek Harness 代理进行良好推理、关注上下文预算,并交接长会话。包含宿主插件和离线轨迹分析器。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:Orliba/dsh-context-keeper#353bc645bf2c9d5a181b633018c9ac925eebab50
README兼容性版本

兼容性与来源证明

Context Keeper 以 dsh-context-keeper 发布,当前版本为 1.0.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/30

版本

1.0.0stable
2026/10/30

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题

相关插件

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

Experimental Session Search@deepseek-ai/dsh-experimental-session-search为 Agents 提供搜索和读取当前工作区早期会话的工具。Hindsight Coding Agents@vectorize-io/hindsight-coding-agents面向编程代理的仅反思式 Hindsight 长期记忆(可插拔支持多种运行框架:opencode、……),自动在后台导入(无需设置 CLI)。Contextdsh-context用于上下文洞察和管理的 DeepSeek Harness 插件,提供上下文仪表板和上下文命令,帮助了解上下文的构成及其演变过程。Memory Plugin@openviking/dsh-memory-plugin适用于 DeepSeek Harness 的 OpenViking 记忆与上下文套件

README

dsh-context-keeper

Two things for a DeepSeek Harness agent:

  • A host plugin that teaches it how to reason well — one persistent system-prompt section, visible on every request.
  • An offline analyzer that reads what it actually thought, from the session files on disk.

It does not cut reasoning short. That was the original goal; measurement killed it. See Why this does not reduce thinking.


Compatibility

  • DeepSeek Harness >= 0.2.0-rc.1 — declared in package.json under dsh.engines.dsh.
  • Node.js >= 22 — the plugin uses the built-in zlib.zstdDecompressSync.
  • Verified on: DSH Desktop 44.7.0 (Windows) — the context badge mounts and renders in the turn footer, and /context-watch / /handoff run against local session files.

The plugin relies on public DSH APIs: systemPrompt.section, commands.register, the conversation.chat.turnTail / conversation.composer.dock seats, and the contextPressure projection. If a future build changes those, the host half warns once and registers nothing instead of taking the host down; the client half simply renders nothing when its projection is unavailable.


What v0.4 adds: a context badge & reminder

A colour dot in every turn's footer (the conversation.chat.turnTail seat — the same place and shape as dsh-cost-meter's usage chip). It reads the official contextPressure projection and paints the band — green (<50%) / yellow (50–65%) / orange (65–80%) / red (≥80%) — with the occupancy percent; the action hint ("建议交接" / "该交接了") only appears from orange up. Hover shows the full sentence.

A reminder panel under the input (conversation.composer.dock) that appears at orange/red only. It states the band and offers an 开新会话 button: it calls the client Remote session.create + session.prompt to make a fresh session in the same workspace and seed it with "read the latest handoff package under .context-keeper/handoff and continue". The new session is a full agent, so it reads the package itself — the button does not inline the package (that would spend tokens again).

Both are pure presentation plus one explicit user click. They never enter the model input on their own and cost zero tokens until you press the button.

Honest limits (verified against this build's source):

  • DSH's ReasoningRow header (above the thinking block) is hard-wired with no extension seat, so the footer is the nearest always-visible open spot.
  • After creating the new session the button cannot switch you to it — the slot API has no navigation; open it from the sidebar. The panel says so.
  • Command names must match ^[a-z][a-z0-9_-]*$ and third-party commands render their name (no separate display label), so /handoff and /context-watch cannot be shown as Handoff/Context-Watch in the menu. Readability goes into the Chinese one-line description shown next to each name instead.

The client half is plugin/client.js (declared under dsh.client in package.json); the host half is unchanged. No config path needed.


What v0.3 adds: context budget & handoff

v0.2 taught the agent how to think. v0.3 handles whether the window can hold it. Two human commands, both reading the session file DSH already writes and calling a model zero times:

  • /context-watch — occupancy, band (green/yellow/orange/red), headroom, growth per turn, and the last compaction's reclaim.
  • /handoff — write a portable handoff package plus a full faithful archive to <workspace>/.context-keeper/handoff/, so a fresh session can continue without re-deriving anything. It reuses DSH's own compaction/summary checkpoint as the "early context" (free multi-level distillation) and quotes the recent tail verbatim.

A short, static context-budget line is added to the system prompt. It holds no numbers on purpose: a changing number in the system prompt would invalidate the provider's prefix cache on every request, which costs more than it saves.

The design and the two references it distils are in docs/distill-design-v3.md.


Install

As a DSH plugin

dsh plugin --profile <your-profile> add dsh-context-keeper

Then restart the profile. The plugin registers one prompt section named context-keeper:how-to-reason at order 650, which places it with the other policy sections — after the deployment persona, before the tool catalog.

To turn it off without uninstalling, either set enabled: false in the config block, or add a patch row:

- id: context-keeper
  disabled: true

Config options:

OptionDefaultMeaning
enabledtruefalse registers nothing
textbuilt-in ruleReplace the rule text entirely
order650Section position in the assembled prompt
maxChars2000Truncate at a paragraph boundary

As a CLI

git clone https://github.com/Orliba/dsh-context-keeper
cd dsh-context-keeper
node bin/cli.mjs --help

No build step, no dependencies, Node >= 22 (uses built-in zlib.zstdDecompressSync).


The plugin: what it puts in the prompt

The rule is five lines, each naming an observable behaviour rather than a virtue:

Decide before acting. Before the first tool call, settle what you are doing, why, and how you will know it worked. Once you state a plan, execute it; do not reopen the plan mid-execution.

Change a conclusion only with a reason. …

When reasoning stalls, gather evidence instead of thinking harder. …

Match depth to risk. Read-only exploration may be quick. Irreversible actions deserve a second look. …

Say what you do not know. …

Full text and the reasoning behind each line: plugin/rule.mjs and docs/rule-text.md.

Why a prompt section and not a stream interceptor

The first design watched the reasoning stream and reacted — lower the effort tier when a trace looked wasteful, stop a turn that ran away. Three measurements, on real sessions, removed the target:

HypothesisMeasuredResult
Looping traces repeat sentences0.1% sentence repetitiondead
Nearby steps re-derive earlier steps0.3% of step pairs above Jaccard 0.35dead
Early commitment + long tail = wastetop candidates read by hand: both productivedead

It also depended on two fragile places: llm/stream (no in-tree consumer) and agent/turn-stopping (fires only after the turn already ended).

A prompt section is the opposite kind of intervention. It is declared once, it is visible on every request, and it needs no detection — the model does not have to be caught in a bad pattern in order to learn from it. Numbers and raw data: docs/calibration.md.

Failure behaviour

systemPrompt.section() is a public registry method, but this plugin still refuses to take a host down if a future build changes shape. If the method is missing, it warns once and registers nothing — the entry stays loaded so the rest of the profile is unaffected.

Two failure modes were found the hard way during development, both now covered by tests:

  • an undeclared service throws at activation (cannot get property X without inject)
  • a declared but never provided service leaves the entry pending forever (waiting for service: X) — this is what happens if you declare console, which is a Node global, not a harness service

The CLI: reading what it thought

# every session under a DSH home, sorted by thinking volume
node bin/cli.mjs scan "$DSH_HOME/sessions"

# one session, aggregate
node bin/cli.mjs report path/to/session.v4.jsonl.zstd

# longest traces first
node bin/cli.mjs traces path/to/session.v4.jsonl.zstd --limit 20

# export candidates for human review, with a verdict checkbox per sample
node bin/cli.mjs samples path/to/session.v4.jsonl.zstd --n 5 --out ./review

# context budget: occupancy, band, headroom, last compaction
node bin/cli.mjs context path/to/session.v4.jsonl.zstd

# write a portable handoff package + full archive for a session
node bin/cli.mjs handoff path/to/session.v4.jsonl.zstd --out ./handoff

--json works on report, traces, and scan.

MetricMeaning
tokensEstimated thinking tokens
parasParagraphs in the trace
commit@Where the first commitment to a plan lands, as a share of the trace
recommitCommitments appearing after that first one
retractStrong retractions ("scratch that", "I was wrong")
tail-effShare of post-commitment paragraphs naming a new artifact or number
churn0..1 composite of the three above

Verdicts: lean, normal, churn-risk, unclear (no commitment found).

Reading the numbers honestly

  • tokens is an estimate (CJK ≈ 1 char/token, Latin ≈ 4 chars/token). Fine for ratios inside one trace, not billing-grade.
  • commit@ matches English and Chinese commitment patterns. Traces in other languages land in unclear rather than being mis-scored.
  • churn is a heuristic never validated against a corpus where waste is known to exist. Treat churn-risk as "worth a look", not a diagnosis.

Session storage facts

Two things that silently corrupt any independent analysis:

  1. Multi-frame zstd. Session files are a sequence of independently framed zstd blocks, not one stream. Node's zstdDecompressSync reads only the first frame. src/zstd.mjs splits on the magic number and decodes each frame.
  2. Reasoning is stored four times per attempt — content[], replayState.blocks[], chunk.block, and chunk.replayState.blocks[]. Walking the event tree counts every trace 4x, with no error and no symptom. Read data.message.content[] only; src/session.mjs explains why.

Layout

bin/cli.mjs         command wiring
src/session.mjs     session file -> reasoning records + full detail (users/tools/compactions)
src/metrics.mjs     pure metric functions
src/budget.mjs      pure context-budget math (occupancy, bands, ETA)
src/handoff.mjs     pure handoff packaging + archive rendering
src/zstd.mjs        multi-frame decoder
src/render.mjs      table/report formatting
plugin/index.mjs    the host plugin (rule sections + /context-watch + /handoff)
plugin/client.js    the client half (turnTail context badge, colour dot)
plugin/rule.mjs     the rule text
test/               plugin, budget, handoff, client-badge, activation and e2e prompt tests
docs/               calibration data and design notes

Run the tests:

npm test                         # everything below, in order
node test/plugin.test.mjs        # unit: what gets registered
node test/activation.test.mjs    # cordis injection rules
node test/client-badge.test.mjs  # badge math + parity with the host + reminder helpers
node test/client-boot.test.mjs   # mounts the client bundle under the real loader shape

License

MIT