DeepSeek Harness Plugin Hub

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

探索

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

社区

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

相关链接

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

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

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

@local/dsh-context-management

Context Management

DeepSeek Harness (DSH) 的窗口化压缩,支持会话私有笔记和分页历史记录召回

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

npx -y @deepseek-ai/dsh plugin --profile web add github:overact/dsh-context-management#b4b25826af2992e655875cd72acba6da26a79c26
README兼容性版本

兼容性与来源证明

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

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

版本

0.3.6stable
2026/10/8
0.3.0stable
2026/9/26

相关插件

正在加载相关插件…

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

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

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

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

认领这个 Plugin →
报告问题

相关插件

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

Hindsight Coding Agents@vectorize-io/hindsight-coding-agents面向编程代理的仅反思式 Hindsight 长期记忆(可插拔支持多种运行框架:opencode、……),自动在后台导入(无需设置 CLI)。Memsearch Dsh@zilliz/memsearch-dsh适用于 DeepSeek Harness 的 MemSearch 插件:在多个代理之间共享 Markdown 记忆,支持捕获、步骤前上下文注入、记忆召回技能和技能候选审核面板。Memory@furongjun1999/dsh-memory灵枢(Lingshu·líng shū)DeepSeek Harness 插件:完整大脑——长期记忆/知识飞轮/自我认知/递归反思接入 DSH,对话自动沉淀进 md_cg 认知图(md 文档)Archive Manager@michengai/dsh-archive-manager归档、恢复、收藏和永久删除会话,并诊断损坏的会话日志。

README

dsh-context-management

English · 简体中文

Windowed compaction, session-private notes and paged history recall for DeepSeek Harness (DSH). The multi-window idea is borrowed from Codex, but this is not a 1:1 port of the Codex API, and it does not promise lossless recovery of every detail.

Compatibility

Version 0.3.6, verified on DSH 0.2.0-rc.2 / Node.js ≥ 22.15. Peer ranges are >=0.1.7-alpha.1 || >=0.2.0-0, admitting the 0.2.0 prereleases with no upper bound on stable releases: since 0.1.7-rc.1, DSH skips at startup any plugin whose peer range excludes the running version, so an upper bound would silently disable the plugin after a DSH upgrade. Compatibility is judged by capability instead, through the preflight check.

  • Works through official DSH extension points: @local/dsh-context-management/compaction subclasses BasicCompactionEngine and overrides the summarize() hook and the dynamically dispatched compactIfNeeded(). No instance monkey-patching, no reads of Cordis internals.
  • Reuses the native tool-call pairing checks, recent-turn retention, maintenance lock, cancellation, shrink check, compaction transaction, persistence and overflow retry.
  • Automatic compaction is still driven by DSH's own callbacks; the plugin adds no loop of its own.
  • The host plugin publishes a contextWindows service (session state and settings); preset engines look it up per call rather than via inject. Without the host, the engine behaves exactly like the native one, so a preset never loses compaction because of a missing dependency.
  • new_context only works in presets that mount this engine; elsewhere it fails with a clear error while the notes/history tools stay usable.
  • The window number only advances once DSH actually commits the replacement messages. Failures, cancellations and "nothing to compact" never report a successful switch.
  • Every window switch builds a bounded handoff. By default (handoffSummary: generated) the native summary model is called once on the outgoing region and its result is wrapped in <generated_handoff>, together with the goal, todos, recent user instructions, recent notes and the window index. The mandatory snapshot is rendered first and the body takes every character left over, so an unused snapshot allowance returns to the body instead of being stranded; optional note previews are bounded so they cannot consume it. An overrun is spent on the sections the host's directive makes most expendable instead of being cut off the end, so every mandated section survives — see the priority trim below. The compaction/summary event records the real provider/model/usage even when the body ends up extractive, so the cost shows up in usage accounting. If that call fails, or the remaining budget cannot carry a usable body, the handoff falls back to an extractive one without blocking the switch, and its window record states why (generated_discarded: budget); handoffSummary: extractive never makes the extra call. Disabling the plugin or its tools falls back to native summaries.

How it works

flowchart TD
  P["Before every agent step"] --> Q{"new_context requested?"}
  Q -- no --> U{"Usage at or above the<br/>auto-compaction threshold?"}
  U -- no --> C["Continue the conversation"]
  U -- yes --> K1["Compact older messages<br/>keep the latest 16% verbatim"]
  Q -- yes --> K0["Compact older messages<br/>keep only the last message"]
  M["Manual /compact"] --> K0
  O["Provider reports context overflow"] --> K0
  K0 & K1 --> S["One call to the summary model"]
  S --> H["Build the handoff: summary + goal/todo<br/>+ last 4 user instructions verbatim + notes + window index"]
  H --> W["Enter window win_N+1<br/>system prompt and tools unchanged"]
  W --> N["Replace handoff.md<br/>append to handoff-log.md"]
  W --> R["Model recovers exact details on demand<br/>with history_* / notes_*"]

All four entry points end in the same switch. If the summary call fails, the handoff falls back to extractive excerpts; with the plugin disabled, DSH's native compaction runs unchanged. The threshold and the verbatim tail are DSH's own settings (thresholdRatio, headroomTokens, retainRatio), which this plugin does not change.

Tools

ToolPurpose
new_contextRequest a window switch at the next safe step boundary
notes_write_file / notes_append_to_file / notes_read_file / notes_list_files_by_prefix / notes_search_contentsSession-private notes that survive window switches and restarts
history_list_windows / history_list_items / history_read_item / history_search_contentsPaged recall over the session's complete raw history. history_read_item also resolves the window-summary, goal and checklist item IDs that every handoff prints

Usage

/ctx toggles the plugin; /compact runs the current compaction mode. The toggle applies to every session of the running DSH instance, not to a single chat tab.

When the model calls new_context it gets back requested, not a reset: the switch is scheduled for the next safe step boundary, after the current step's tool results are fully written to history. Explicit switch requests are honoured even when DSH's auto compaction is off.

The web "Context management" settings page uses DSH 0.2.0 configForms and shares its backend setting with /ctx. Read failures, read-only connections and failed saves are never shown as a successful toggle. Settings changes need no restart. Every registration goes through the Cordis lifecycle, so a hot swap (dispose + re-apply) removes all ten tools, the /ctx command, the prompt section and the contextWindows service, then re-installs exactly one of each while notes are rebuilt from their durable store; the preset engine re-binds to the fresh store per call and falls back to native summaries while no host is mounted. DSH's hmr entry watches only its configured root directories, so add this plugin's lib there to reload on source edits; otherwise reload the plugin or restart DSH, then refresh the page after upgrading the plugin code.

Storage and recovery

History is read straight from the caller's own immutable DSH session log:

  • item_<seq> is a stable event address; nothing is indexed twice and old records are not dropped past 2,000 entries.
  • Native tool results are linked to their names by call ID; tool/code-dispatch (PTC) is searchable too.
  • history_read_item with format: "json" pages through complete raw events, including call arguments and metadata.
  • Windows are delimited by native checkpoint-replacement events. Old events kept in the retained tail still belong to the window that produced them.

Notes are isolated per session under self/notes/<path>; there is no arbitrary cross-session read/write. They live in the plugin's own directory, $DSH_HOME/context-management/notes/<sessionId>.json ($DSH_HOME resolved by dsh-home-paths), independent of the session-persistence backend's private layout, and are written with DSH's atomic write and cross-process file lock. A failed write never swaps unsaved state into the cache.

After every committed window switch (automatic, /compact or new_context) the plugin writes two notes itself: handoff.md is replaced with the latest full, unclipped handoff (for a generated handoff, the summarizer's raw output), and handoff-log.md gains one line with the window, time, summary item and first line. Only the latest handoff is kept in full, because each generated summary already merges the previous one; earlier handoffs stay readable through history_read_item. Neither note is injected into the next handoff, whose body already carries the same text. A cancelled or failed compaction writes nothing, and a failed note write is logged without blocking the switch.

Notes load on demand, not for every session at startup. On restore, window metadata is rebuilt and that session's notes are loaded; an unfinished transient switch request is not re-executed after a restart.

Include context-management/notes/ when backing up or migrating; deleting a session does not delete its notes file. Forked sessions get independent notes; parent notes are not implicitly shared.

Limits

OperationDefault / hard limit
Window handoff (handoffMaxChars)16,000 characters by default, configurable 8,000–32,000
Injected notesUp to the 8 most recent, ~1,800 characters each, within the handoff budget
Single note file1,000,000 UTF-8 bytes
Notes per session64 files / 4,000,000 UTF-8 bytes; over-limit writes are rejected, never silently evicted
History list / search20 items by default, 50 max; 400 characters per item by default, 1,000 max
History scan per pageUp to 2,000 events or ~2,000,000 content characters; a single large event is checked in full
History preview per pageUp to 12,000 characters in total, plus item metadata
History / note body reads8,000 characters by default, 20,000 max
Note searchUp to 10 files × 5 lines; 400 characters per line

History queries return has_more and next_cursor; keep the same filters and order when continuing. Body reads continue with next_offset_chars. Search is case-sensitive unless case_sensitive: false.

The last four user instructions are quoted in chronological order, up to 1,000 characters each, with their event addresses, later corrections taking precedence. The handoff also keeps the active goal, open todos and a bounded set of recent notes; exact raw evidence is recovered through the history tools.

The host's directive mandates eight sections and writes ## Critical Context last, so a plain tail cut deletes decisions, constraints and open questions before anything else. The body is therefore clipped by priority instead of from the end. Every piece — the preamble and each ## section — first keeps a marker reservation, so the priority split never empties a piece without a marker, and then a small floor so it keeps some text of its own; only the rest is split by weight. A floor is a share of the budget, not a promise that a whole bullet or a complete path survives inside it. Critical Context, Next Step, Pending Jobs and Current Work receive the larger shares, and Files and Code (the long path and snippet excerpts) gives ground first. That ordering is a preference, not a guarantee: when the sectioned layout fits, every section keeps its heading, but a section is still shortened when the budget cannot cover the reservation its heading and marker need. A cut that lands inside a fenced code block closes it with a synthesized delimiter instead of leaving it open — an open fence would turn every following heading into code and cost the next compaction the sections after it. Where the delimiter does not fit, the repair retreats out of the block instead, and the receipt rather than a marker reports what it dropped, because a marker would sit inside the block too; where it would have to delete every remaining character, it is refused and the excerpt is handed on as it stands. A cut never splits a surrogate pair.

A trimmed section ends with the … [truncated] marker, and a mechanically generated <clipping_receipt> line beside the body states how many source characters were kept, names the pieces this clip shortened with their kept and original lengths, and points at this window's summary item (history_read_item in JSON mode) for the untrimmed reply. A marker written by the summarizer is not durable evidence that a section is partial; the receipt is, and it survives into the next checkpoint. The receipt describes this clip only — it cannot certify that the summarizer omitted nothing — and it reports the reason when the reply is not sectioned at all or when the sectioned layout did not fit the budget. Its reservation is taken only when the reply actually has to be clipped.

Installation

This plugin is not published to npm; the @local/ scope marks it as a local plugin. Using the web profile as an example:

  1. Clone and install dependencies:

    git clone https://github.com/overact/dsh-context-management.git
    cd dsh-context-management && npm install
    
  2. Run the preflight check to confirm the installed DSH provides every capability the plugin needs and nothing in the profile collides with it:

    npm run preflight -- --profile web
    
  3. In the profile directory ($DSH_HOME/profiles/<profile>/), add a local link to dependencies in package.json, then run pnpm install there:

    "@local/dsh-context-management": "link:<plugin-dir>"
    
  4. Register the plugin in the profile's cordis.patch.yml (see Configuration below).

  5. Mount the windowing engine in the web presets (see DSH web preset scope):

    node scripts/sync-presets.mjs --profile web
    

    The script re-runs the preflight before writing and leaves the profile untouched if it fails.

  6. Restart DSH and refresh the page.

Preflight check

scripts/preflight.mjs checks that the target DSH actually provides each capability the plugin uses, and that nothing in the profile collides with it. It never compares version numbers: the requirement list is extracted from the lib/ sources (DSH imports, ctx.<service>.<method> calls, events, session-log event types, base-class hooks, tool and command names), so new usages in the code are covered without touching the check.

CheckLevelWhat it verifies
DSH importsfailThe target DSH packages really export the functions/classes the plugin imports
Compaction hooksfailBasicCompactionEngine's prototype has the methods the plugin overrides or calls (summarize(), compactIfNeeded())
Host servicesfailThe packages providing the services the plugin calls (tools, sessions, commands, systemPrompt, settings) have those methods
Host events, session-log typesfailDSH still emits the events and session event types the plugin listens for
Web presetsfailSome shipped preset mounts the native engine, so the windowing engine has a slot to take
Notes storagefailThe notes directory under $DSH_HOME is writable
Tool and command namesfailNeither DSH itself nor another profile plugin defines a tool or command with the same name
Preset ownershipfailThe profile does not already override the same presets outside the generated block
Web client packages and serviceswarnThe client packages and configForms/slots/locale services behind the settings page exist; without them /ctx still works
Other compaction engineswarnOther profile plugins built on the compaction engine, to check they do not replace the same preset rows

It exits with code 1 when any fail-level check fails. sync-presets.mjs runs it before writing and in --check; run --check from your DSH start-up script and every start after an upgrade re-checks the capabilities. --remove (rollback) skips it.

Configuration

- insert:
    - id: context-management
      name: '@local/dsh-context-management'
      config:
        enabled: true
        overrideCompaction: true
        injectTools: true
        defaultStrategy: window      # or native: models not listed in modelPolicies use native summaries
        modelPolicies: []            # e.g. [{ provider: deepseek, model: deepseek-chat, strategy: native }]
        handoffSummary: generated    # or extractive: no extra model call
        handoffMaxChars: 16000       # 8000–32000
KeyDefaultMeaning
enabledtrueEnable context management for every session of this DSH instance; this is what /ctx toggles
overrideCompactiontrueReplace native summaries with window handoffs (summary + goal/todo + recent instructions + notes + window index) plus history recall
injectToolstrueProvide the notes/history/new_context tools; when off, native summary compaction is used
defaultStrategywindowDefault compaction strategy; native makes unlisted models use native summaries
modelPolicies[]Per exact provider/model strategy overrides; the first match wins
handoffSummarygeneratedBody of the handoff: generated calls the native summary model once; extractive only excerpts records
handoffMaxChars16000Maximum characters of the window handoff

injectTools: false removes the tools and uses native summaries, so history is never trimmed without a way to recover it. overrideCompaction: false keeps the notes/history tools while regular auto compaction and /compact use native summaries; the model can still request new_context explicitly.

Unloading the host plugin removes the tools, the settings registration and the contextWindows service; preset engines then fall back to native summaries.

DSH web preset scope

The web host provides no global compaction; compaction engines live in each preset's isolated scope. The loader cannot patch rows nested in a preset's config.plugins by id (only group: true lists are indexed), and a patch cannot rename a row. So scripts/sync-presets.mjs copies each dsh-web-app preset that mounts dsh-compaction-basic (currently standard/ptc/cordis) in full into a generated block of the profile patch, swapping only that row for @local/dsh-context-management/compaction; presets defined by the profile itself are swapped in place.

node scripts/sync-presets.mjs            # generate/refresh (saves cordis.patch.yml.pre-sync first)
node scripts/sync-presets.mjs --check    # exit code 1 when the block is stale for the installed DSH (parsed YAML: re-folded lines and the profile's own additions to the block don't count)
node scripts/sync-presets.mjs --remove   # delete the block and restore native rows (full rollback)

Re-run it after every DSH upgrade, or those three presets stay on the old definitions. Running --check from your DSH start-up script gives a log warning when they go stale. Do not edit standard/ptc/cordis in the web editor: the script refuses to write if it finds a same-id override outside the generated block. Adding to a restated row inside the block is yours to keep and is not stale, but a regeneration rewrites the block and drops those additions — the previous file stays as cordis.patch.yml.pre-sync.

Verification

npm install
npm run verify

Tests need the DSH dev dependency; alternatively point DSH_PACKAGE_DIR at an installed @deepseek-ai/dsh package directory. All model responses are fixed local fixtures, so the tests never call a paid model. They run in a single-process Node test runner to avoid restarting the DSH test runtime.

Coverage includes the real Cordis lifecycle, DSH ToolRuntime, SettingsProvider, TokenMeter, BasicCompactionEngine and JSONL disk recovery, plus web settings binding, session isolation, tool pairing, cancellation, failure paths and capacity limits. The web tests check the state/write contract; they are not a full visual browser test.

History reads are incremental: building state for 10,000 synthetic events takes ~2.5 ms the first time, and an unchanged re-read scans 0 events (timings are indicative only; the regression tests pin incremental reads, scan limits and output limits).

0.3.6 passes 108 tests on DSH 0.2.0-rc.2, including the preflight: a stand-in DSH missing one hook must make it report exactly that capability.

Code layout

ModuleResponsibility
lib/index.jsHost plugin: config schema, tool and command registration, contextWindows service, settings changes
lib/compaction.jsPreset compaction engine, a BasicCompactionEngine subclass that falls back to native behaviour without the host
lib/window-controller.js / window-engine.js / window-policy.jsWhen to switch windows, building the handoff, per-model strategy
lib/handoff-note.jsWriting handoff.md and handoff-log.md after each committed switch
lib/session-state.jsIncremental per-session state projection (windows, goal/todo, pending requests)
lib/history-store.js / lib/tools/history.jsPaged session-log recall and the history tools
lib/notes-store.js / lib/note-repository.js / lib/tools/notes.jsIn-memory note model, locked atomic persistence, the notes tools
lib/tools/new-context.jsThe new_context tool
lib/text.jsMessage text extraction and clipping
lib/section-budget.jsPriority-aware clipping of a generated handoff, so no mandated section is deleted by an overrun
lib/client.jsWeb settings page (lazy-CJS client module)
scripts/preflight.mjsPre-install capability check
scripts/sync-presets.mjs / presets.mjs / dsh-env.mjsPreset sync CLI, preset rewriting, locating DSH and the profile

License

MIT