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
M

dsh-memory-plugin

Memory Plugin

为 DeepSeek-Harness (dsh) 提供三个宿主插件:L1 跨会话短期记忆(由钩子驱动的捕获与召回,零依赖)、memory_save 工具和 memory-timer 定时维护任务。

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

npx -y @deepseek-ai/dsh plugin --profile web add github:YaoQC-Ai/dsh-memory-plugin#93b387cfa43ea2a23f839c16b4d04b8828c04b05
README兼容性版本

兼容性与来源证明

Memory Plugin 以 dsh-memory-plugin 发布,当前版本为 0.2.2。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

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

版本

0.2.2stable
2026/10/19
0.2.0stable
2026/9/30
0.1.1stable
2026/9/24
查看其余 1 个版本收起版本
0.1.0stable
2026/9/7

相关插件

正在加载相关插件…

最新版
0.2.2
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
any
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/19
查看源码 ↗
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-memory-plugin

v0.2.2:面向 DSH ≥0.2.0(在 0.2.0-rc.1、0.2.0-rc.2 与 0.2.1-rc.2、Node.js 24 验证);不等于已验证所有 DSH 版本。0.1.x 旧宿主不再支持。

0.2.2: re-verified against DSH 0.2.1-rc.2 — runtime files byte-identical to 0.2.0/0.2.1. Diffed every host API the plugin touches (agent/created, session/event shapes, append(…,{surfaceOp}), pre-step waterfall, surface, V4 admission, form:'recall'): all unchanged; SESSION_FORMAT_VERSION stays 4. The boot gate evaluates engines.dsh with includePrerelease, so >=0.2.0-rc.1 <0.3.0-0 already admits 0.2.1-rc.2. Host harness default moves to 0.2.1-rc.2. The experimental appendPluginRecord API is gated to packages/experimental/ callers only and is intentionally not adopted. 0.2.2:针对 DSH 0.2.1-rc.2 重新核验——运行件与 0.2.0/0.2.1 逐字节相同。逐文件比对了插件依赖的每个宿主 API(agent/created、session/event 形状、append(…,{surfaceOp})、pre-step waterfall、surface、V4 admission、form:'recall'):全部未变;SESSION_FORMAT_VERSION 仍为 4(无 v4→v5 迁移)。boot 闸门用 includePrerelease 评估 engines.dsh,故现有 >=0.2.0-rc.1 <0.3.0-0 已放行 0.2.1-rc.2。可选宿主集成默认期望版本改为 0.2.1-rc.2。实验性 appendPluginRecord/pluginRecordOf 仅限 packages/experimental/ 调用,本插件有意不采用。

0.2.1: declarations and verification only — no behavior change. The optional host harness now defaults to 0.2.0-rc.2, and package.json gains a forward-looking engines.dsh range (>=0.2.0-rc.1 <0.3.0-0) because DSH 0.2.1-alpha.4+ reads engines.dsh first and falls back to peerDependencies. 0.2.1:只补声明与验证,行为不变。可选宿主集成默认期望版本改为 0.2.0-rc.2;package.json 新增前瞻性的 engines.dsh(>=0.2.0-rc.1 <0.3.0-0),因为 DSH 0.2.1-alpha.4 起优先读 engines.dsh、其次才回退 peerDependencies。

0.2.0: recall injection moved off the removed agent/session-start onto agent/created (injecting only on source: startup | clear, and carrying source.form: 'recall' for the UI's context-recall rendering); capture now accumulates per-turn text from session/event instead of the deprecated snapshotEvents()/eventAt() reads; and a peerDependencies gate on @deepseek-ai/dsh ^0.2.0-rc.1 makes an incompatible host skip this bundle at boot instead of failing every turn mid-conversation. The producer-owned plugin:memory-shortterm source kind and recognition of pre-0.2 rows are unchanged.

0.2.0:召回注入从已删除的 agent/session-start 迁到 agent/created(仅在 source: startup | clear 时注入,并带 source.form: 'recall' 以走 UI 的上下文召回渲染);捕获改为从 session/event 增量累积本轮文本,不再用已废弃的 snapshotEvents()/eventAt() 回扫;新增对 @deepseek-ai/dsh ^0.2.0-rc.1 的 peerDependencies 闸门,使不兼容宿主在 boot 期跳过本组合包,而非每个回合在对话中途失败。生产者自有的 plugin:memory-shortterm kind 与对 0.2 之前旧行的识别保持不变。

Cross-session short-term memory (L1) for DeepSeek-Harness (dsh). Zero dependencies, zero build step — plain Node built-ins and an inlined UserMessage.

One package, three host plugins (each is a cordis.patch.yml row; this README focuses on the L1 plugin and summarizes its siblings):

Plugin rowFileWhat it does
dsh-memory-pluginindex.jsL1 short-term cross-session memory — capture / recall / evict / recover (this document)
dsh-memory-plugin/savesave.jsmemory_save model tool — writes a concept page into <dir>/memory/knowledge/
dsh-memory-plugin/timertimer.jsmemory-timer — scheduled maintenance task (default 02:00 wall-clock, dry-run safe)

为 DeepSeek-Harness(dsh)提供跨会话短时记忆(L1)。零依赖、零构建 —— 纯 Node 内置模块 + 内联构造 UserMessage。

一个包、三个宿主插件(每个都是 cordis.patch.yml 的一行;本 README 详述 L1 插件,并概述两个兄弟插件):

插件行文件作用
dsh-memory-pluginindex.jsL1 跨会话短时记忆 —— 捕获 / 召回 / 淘汰 / 恢复(本文档)
dsh-memory-plugin/savesave.jsmemory_save 模型工具 —— 把概念页写入 <dir>/memory/knowledge/
dsh-memory-plugin/timertimer.jsmemory-timer —— 定时维护任务(默认本地时钟 02:00,dry-run 安全)

English

What it does

Makes an agent remember what recent sessions talked about when a new session starts.

  • Capture — captures session/event → turn/end only when reason.kind === 'completed', once per live session turn.
  • Recall — on agent/created (source startup/clear), checks claimed and pending memory before injecting recent digests; resume/compact skip re-injection.
  • Recover — restores the accepted current-step messages after compaction, or the rebuilt request during a same-step overflow retry.

Capture is rule-based text extraction: no extra LLM calls. Local file I/O is synchronous; failures are logged. It is not a semantic summarization pipeline.

How it works

Four business listeners; no services injected (the fake dispose-event guard was dropped — Cordis auto-detaches listeners when the fiber unloads):

EventAction
agent/createdOn startup/clear: deduplicate claimed/pending memory, then inject recall (resume/compact skip)
session/eventAccumulate this turn's user/assistant text; capture on turn/end when reason.kind === 'completed'
agent/pre-stepAfter next(), update decision.messages, preserve extra fields, settle own pending messages
agent/request-errorOuter prepend listener: await compaction recovery, append recall only for an uncancelled overflow retry with a newer surface generation

Empty first steps and rejected steps stay unchanged. Retry recovery does not authorize retries, change the compactor's checkpoint/counts, or add an extra step. Capture deduplication is in-process only; aborted/error/empty turns and historical seed events are not captured. A committed event is not a disk-flush guarantee.

Session-event shapes are asymmetric (verified against packages/core/session/src/types.ts):

user/message      → data IS the UserMessage        (use data.content, ONLY when data.source.kind === 'user')
assistant/message → data is {turn, step, message}   (use data.message.content)
turn/start        → data is {turn}                  (opens a fresh per-turn capture buffer)

DSH also injects scaffolding — the workspace AGENTS.md, runtime-context snapshots, the skills catalog — as user/message events, each stamped with its own source.kind. Only a genuine user prompt carries source.kind === 'user' (the headless bundle and session-controller both stamp it so, and DSH's own tests discriminate injected context by source.kind !== 'user'). Capture (turnTextOf) therefore whitelists kind === 'user' rather than blacklisting known plugin kinds — the source map is merge-extensible, so a blacklist would leak every newly added injection kind. Without the filter the digest fills with boilerplate that is then re-injected as "background" and amplified each session.

session.append only checks JSON round-trip safety, not a strict per-field schema — so an inlined frozen literal with a fresh randomUUID() injects exactly like llm.createUserMessage(), with no import of DSH internals.

Install

From a git host (pnpm links the checkout; nothing is built):

dsh plugin --profile <name> add github:YaoQC-Ai/dsh-memory-plugin

From a local checkout:

dsh plugin --profile <name> add ./dsh-memory-plugin

Verify the layer, then start:

dsh --profile <name> --dump-config   # shows a "# == dsh-memory-plugin" layer
dsh --profile <name>

The package declares peerDependencies: { "@deepseek-ai/dsh": "^0.2.0-rc.1" }. On an incompatible host, dsh skips this bundle at boot with a stderr warning (its three plugin rows vanish from --dump-config) instead of failing every turn mid-conversation. The package also declares engines.dsh: ">=0.2.0-rc.1 <0.3.0-0"; hosts from 0.2.1-alpha.4 check that field before the peer range, so the same gate keeps working there.

Configuration

Every knob is optional; add a config: block to the patch row to override.

KeyDefaultMeaning
dir$DSH_HOME or ~/.dshBase dir; digests live under <dir>/memory/shortterm/
maxChars2048Cap on the injected digest
maxEntries50Turns kept per session file
recentFilesCap20Session files aggregated on recall (most recent first)
assistantMaxChars280Truncation length for a single assistant line in the digest
maxCandidates500Evicted-turn candidates kept in compile_candidates.md (the L1 aging archive — excluded from recall so it cannot pollute the injected digest)

Storage

<dir>/memory/shortterm/
├── <session-id-1>.md    # newest turn first, capped at maxEntries
├── <session-id-2>.md
└── ...

Evicted turns are not dropped: they roll into <dir>/memory/shortterm/compile_candidates.md (a shared aging archive, capped at maxCandidates). That file lives beside the per-session digests but is excluded from recall — buildDigest never reads it, so the archive cannot crowd out real recency or be re-injected as "background". Entry boundaries in both files are ## <ISO timestamp> lines; Markdown headings like ## foo inside an assistant reply stay part of their turn and are not split into fake entries.

Per-session files reduce write collisions, but the shared candidate archive has no cross-process lock. Digests are not the source of truth; retain the host session logs for recovery.

Sibling plugins in this package

  • memory_save (save.js) — a model tool that writes a self-contained concept page into <dir>/memory/knowledge/ (maintaining <dir>/memory/knowledge/_index.md). It takes title (concept name), content (self-sufficient body) and domain, one of persona | execution | knowledge; it validates that the value is one of those three before writing. This is the write half of L2 — the read/retrieval half (memory_search) is not implemented yet.
  • memory-timer (timer.js) — a scheduled maintenance task: each wall-clock day at 02:00 (configurable via hour / minute on the patch row) it fires once and — by default — dry-runs: it appends a trigger receipt to <dir>/memory/_log.md and records state in <dir>/memory/timer-state.json, so you can observe the cadence before wiring it to real work. Consecutive failures are tracked against failAlertThreshold. It injects timer (ctx.interval) from the base bundle's cordis-plugin-timer.

Optional: add L3 semantic recall

L1 gives recency; it does not do semantic search. For that, layer the official Memorix MCP memory example MCP memory server in your own profile's cordis.patch.yml (do not fork it into this package — it needs an external memorix binary, and forcing it would break installs that don't have one):

- insert:
    - id: memory-memorix
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: memorix
        transport: stdio
        command: memorix
        args: [serve]
        cwd: !!js process.cwd()

This exposes mcp__memorix__* tools the model can call natively.

Roadmap (not in this slice)

  • L2 compile — scheduled LLM compilation of digests into concept pages (topics / decisions / todos). The write half of the wiki (memory_save) already ships; the scheduled compiler and memory_search retrieval do not.
  • N1 — session full-text search is disabled by default in dsh; a session-query patch override will accompany the memory_search iteration.

Development

npm test
# Optional: DSH_SOURCE must point to a built 0.2.1-rc.2 source tree (override the expected version with DSH_EXPECTED_VERSION).
npm run test:host

The 41 unit tests require no host dependencies. The optional integration harness uses real host drivers with a simulated provider, temporary storage and no network. Tests are included in Git, not in the npm runtime package.

License

MIT


中文

它做什么

让 agent 在新会话开始时「记得」最近若干会话聊过什么。

  • 捕获 —— session/event → turn/end 且 reason.kind === 'completed' 时,按轮次提取 user + assistant 文本,写入会话摘要。
  • 召回 —— agent/created(source 为 startup/clear)检查已认领与 pending 中是否已有记忆,再注入近期摘要;resume/compact 不重复注入。
  • 恢复 —— 压缩后修正当前步最终消息;溢出压缩后,在同一步重试重建请求前恢复记忆。

捕获是规则化文本提取,不增加模型调用;本地文件 I/O 是同步的,失败记告警。它不是语义摘要流水线。

工作原理

四个业务监听器,不注入服务(已去掉那个挂在不存在事件上的 dispose 守卫 —— Cordis 会在 fiber 卸载时自动摘除监听器):

事件动作
agent/createdstartup/clear 时检查已有记忆,必要时注入召回(resume/compact 跳过)
session/event增量累积本轮 user/assistant 文本,turn/end 且 reason.kind === 'completed' 时落盘
agent/pre-stepawait next() 后修正 decision.messages,保留扩展字段,清理本插件 pending
agent/request-errorprepend 外层等待压缩器恢复;仅在溢出 retry、未取消且 surface generation 增加时追加记忆日志

空首步、reject 不恢复;后续工具续步不受空首步规则影响。retry 恢复不自行授权重试,不改压缩器计数或 checkpoint,不产生额外 step。去重仅限进程内;取消、错误、空轮次和历史 seed 不捕获。事件提交不代表已经 flush 到磁盘,进程崩溃后的漏捕获不自动补偿。

会话事件形状不对称(已对照 packages/core/session/src/types.ts 核对):

user/message      → data 本身就是 UserMessage     (取 data.content,且仅当 data.source.kind === 'user')
assistant/message → data 是 {turn, step, message}  (取 data.message.content)
turn/start        → data 是 {turn}                 (开启本轮捕获缓冲)

DSH 还会把工作区 AGENTS.md、runtime-context 快照、skills 目录这些脚手架也作为 user/message 事件注入,各自带着不同的 source.kind。唯有真实用户 prompt 才是 source.kind === 'user'(headless bundle 与 session-controller 都如此打标,DSH 自身测试也用 source.kind !== 'user' 区分注入上下文)。因此捕获过滤(turnTextOf)采用白名单 kind === 'user',而非黑名单已知插件 kind——source map 可被插件扩展,黑名单会漏掉每一种新增的注入 kind。不加这道过滤,digest 会被样板塞满,再作为「背景」注入下一会话,逐次放大。

session.append 只校验 JSON 无损可序列化,不做逐字段严格 schema 校验 —— 所以内联一个带新 randomUUID() 的冻结字面量,注入效果与 llm.createUserMessage() 完全一致,且无需 import 任何 DSH 内部模块。

安装

从 git 托管安装(pnpm 链接该 checkout,不跑任何构建):

dsh plugin --profile <name> add github:YaoQC-Ai/dsh-memory-plugin

从本地 checkout 安装:

dsh plugin --profile <name> add ./dsh-memory-plugin

先验证层、再启动:

dsh --profile <name> --dump-config   # 会显示一层 "# == dsh-memory-plugin"
dsh --profile <name>

本包声明 peerDependencies: { "@deepseek-ai/dsh": "^0.2.0-rc.1" }。宿主不兼容时,dsh 会在 boot 期跳过本组合包并往 stderr 打警告(--dump-config 里三行插件消失),而不是让每个回合在对话中途失败。本包同时声明 engines.dsh: ">=0.2.0-rc.1 <0.3.0-0";0.2.1-alpha.4 起的宿主先查这个字段、再回退 peer 范围,因此同一道闸门在新宿主上依然生效。

配置

所有旋钮都可选;在 patch 行补 config: 块即可覆盖。

键缺省含义
dir$DSH_HOME 或 ~/.dsh基准目录;摘要存放在 <dir>/memory/shortterm/
maxChars2048注入摘要的字符上限
maxEntries50每个会话文件保留的轮次条数
recentFilesCap20召回时聚合的会话文件数(最近优先)
assistantMaxChars280摘要里单条助手文本的截断长度
maxCandidates500compile_candidates.md 候选池保留的淘汰轮次块数(L1 老化留档 —— 召回时排除,不会污染注入摘要)

存储

<dir>/memory/shortterm/
├── <session-id-1>.md    # 最新轮次在最前,上限 maxEntries
├── <session-id-2>.md
└── ...

被挤出的轮次不丢弃:滚动进入 <dir>/memory/shortterm/compile_candidates.md(全会话共享的老化留档,上限 maxCandidates)。它与各会话摘要同目录,但召回时被排除 —— buildDigest 从不读它,所以留档不会挤占「近期性」、也不会被当作「背景」重新注入。两类文件的条目边界都是 ## <ISO 时间戳> 行;assistant 正文里的 Markdown 标题(如 ## foo)仍属于本轮,不会被误切成伪条目。

按会话分文件可减少写入冲突,但共享候选池没有跨进程锁。摘要不是事实源,恢复依据仍是宿主保留的完整会话日志。

同包兄弟插件

  • memory_save(save.js) —— 一个模型工具:把自足的概念页写入 <dir>/memory/knowledge/(并维护 <dir>/memory/knowledge/_index.md)。入参 title(概念名)、content(自足正文)、domain(三选一:persona 用户/人格 · execution 工作方式 · knowledge 其它),写入前校验取值必须属于这三者。这是 L2 的写半边;读/检索半边(memory_search)尚未实现。
  • memory-timer(timer.js) —— 定时维护任务:每个自然日本地时钟 02:00(patch 行 hour/minute 可改)触发一次,默认只 dry-run:向 <dir>/memory/_log.md 追加触发凭证、状态记入 <dir>/memory/timer-state.json,便于先观察节奏再接真实任务;连续失败次数按 failAlertThreshold 跟踪告警。它从 base bundle 的 cordis-plugin-timer 注入 timer(ctx.interval)。

保存与定时配置(v0.1.1)

  • memory-save.config.wikiDir:可选绝对路径,优先于 dir;未设时仍写 <dir>/memory/knowledge/。升级有本机定制路径的安装前,必须显式配置旧落点。
  • 标题含非法字符、Windows 设备名、内部保留页名、尾随点/空格或超过 80 字符时直接拒绝;不靠删除字符或截断来改名。概念页与索引不提供跨文件事务。
  • memory-timer.config.enabled: false:完全禁用启动补跑和轮询。只允许一个进程启用 timer,建议 Web 启用,headless 禁用。
  • 同目录临时文件替换可降低状态截断风险,但不是跨进程互斥,也不是 _log.md 与状态文件的事务。
  • 整机休眠后,下一次 Web 启动或轮询只补最近一个边界;连续两晚观察须使用新部署后的真实记录。

profile patch 示例(这是两个 profile 各自的片段,不要合并):

# headless/cordis.patch.yml
- id: memory-timer
  config:
    enabled: false
# web/cordis.patch.yml
- id: memory-timer
  config:
    enabled: true

wikiDir 应在两个 profile 中均指向同一个实际绝对路径。patch 会替换整个 config,不是深层合并;保留现有其他配置项。包默认不指定任何用户路径。

可选:叠加 L3 语义召回

L1 提供的是「近期性」,不做语义检索。要语义召回,请把官方的 Memorix MCP memory 示例 MCP memory 服务叠进你自己 profile 的 cordis.patch.yml(不要 fork 进本包 —— 它需要外部 memorix 二进制,强加进来会让没装它的用户安装即坏):

- insert:
    - id: memory-memorix
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: memorix
        transport: stdio
        command: memorix
        args: [serve]
        cwd: !!js process.cwd()

它会暴露 mcp__memorix__* 工具,模型可原生调用。

路线图(不在本切片内)

  • L2 编译 —— 定时用 LLM 把摘要编译成概念页(主题 / 决定 / 待办)。概念页的写半边(memory_save)已随包落地;定时编译器与 memory_search 检索尚未实现。
  • N1 —— dsh 的会话全文搜索默认关闭;session-query 的 patch 覆盖将随 memory_search 迭代一起提供。

开发

npm test

41 项单测无需宿主依赖。可选真实宿主集成测试使用已构建的 0.2.1-rc.2 源码(期望版本可用 DSH_EXPECTED_VERSION 覆盖)、真实驱动与压缩器、模拟提供方和临时目录,不访问网络:

$env:DSH_SOURCE = '<已构建的宿主源码绝对路径>'
npm run test:host

测试代码随 Git 发布,不包含在 npm 运行包中。

许可

MIT