dsh-plugin-sodamem

DSH PLUGIN记忆与知识

仓库 SodaMem/dsh-plugin-sodamem · npm dsh-plugin-sodamem

记忆与知识 L5 · 运行验证通过 安全审查:低风险 可信度:金 可安装插件
安装这个插件

DSH plugin 接入 SodaMem 引擎,为 DeepSeek Harness 提供长期记忆:每轮自动注入证据记忆并回写已结束会话,无需模型调用工具。

验证等级 L5 L5 · 运行验证通过
GitHub 星标 2 复刻 1 · 未关闭 issue 未标注
最近更新 2026-08-18 创建于 2026-08-16
README 12.7 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add [email protected]
兼容 DSH 版本0.2.0-rc.2 等 12 个版本版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名dsh-plugin-sodamem可用 npm view 查看包信息

能做什么

5 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

dsh-plugin-sodamem:为 DeepSeek Harness 提供自动召回与保留的长期记忆能力

  • 自动回忆证据
  • 自动回写会话
  • 事实可溯源
  • 事实自动过期
  • 零模型调用

适用场景

记忆

上游标签

cordisdeepseek-harnessdsh-pluginmemory

验证等级与安全审查

L5 · 运行验证通过
自动化流程结论,不是人工审核
验证等级L5 · 运行验证通过在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来
安全审查低风险静态分析结论,未标注不代表已通过审查
仓库健康度稳定按仓库活跃度与最近更新时间给出
可信度金综合仓库活跃度与验证结果

上面的结论来自上游最近一次自动化验证(2026-10-08): 同一套检查会在插件发新版后重跑,页面显示的是最新一次的逐项结果。

逐项检查结果

L1 · 已找到 ✓ 通过
  • L1.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L2 · 结构化 ✓ 通过
  • L2.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L3 · 安装规范 ✓ 通过
  • L3.1_INSTALL_COMMAND_PARSED 安装命令已解析 方式:安装规范解析
  • L3.2_DSH_VERSION_DECLARED DSH 版本已声明 方式:DSH 版本声明
L4 · 安装已测 ✓ 通过
  • L4.1_INSTALL_EXECUTED_CONFINED 受限沙盒内执行安装 方式:沙盒安装执行
  • L4.2_INSTALL_SUCCESS 沙盒安装成功 方式:沙盒安装执行
  • L4.3_ARTIFACT_CONFIRMED 安装产物已确认 方式:沙盒安装执行
  • L4.4_RESOLVED_ARTIFACT 安装版本已解析 方式:沙盒安装执行
L5 · 运行已测 ✓ 通过
  • L5.1_INSTALL_PASSED_SANDBOXED 沙盒安装通过 方式:沙盒安装执行
  • L5.2_WEB_BOOT_READY Web 启动就绪 方式:Web 启动
  • L5.3_HTTP_SERVED HTTP 服务响应 方式:HTTP 请求
  • L5.4_PLUGIN_INVENTORY_ACTIVE 插件清单中已激活 方式:插件清单查询

风险详情

  • 审查结论 通过
  • 结论说明 vet 静态分析未发现可疑行为,判定为干净(clean)。
  • 风险计数 严重 0 / 高 0 / 中 0
  • 风险详情 未发现严重或警告级问题。

仓库档案

记忆与知识
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方SodaMem仓库 dsh-plugin-sodamem · 默认分支 未标注
分类记忆与知识memory
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言TypeScript仓库主语言
许可证Apache-2.0商用或二次分发前请确认条款原文
星标 / 复刻 / issue2 / 1 / 未标注收录时的数值,非实时
创建 / 更新2026-08-16 · 2026-08-18最后推送 未标注
本站收录2026-08-22首次进入本站目录的时间

README 全文

12.7 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-plugin-sodamem

Long-term memory for DeepSeek Harness, backed by SodaMem.

  • Recall — while a turn is being assembled, the plugin retrieves an evidence block for that turn's question and contributes it to the prompt. BM25 + vector + entity fusion, no model call.
  • Retain — when the turn closes, its messages are ingested back into the store.

Neither is a tool call, so the model can't skip either one and neither costs tool-schema space.

SodaMem is a separate open-source memory engine that runs as a local daemon. This repo is only the dsh plugin; you need the daemon running for it to do anything.

What you get that a notes file doesn't

Every recalled fact names the turn it came from. This is one line of a real evidence block, verbatim:

support=I flew United to Boston last week.
predicate=User flew United to Boston
entities=airline=United|destination=Boston
source=s4/s4_turn_0        ← the actual turn, not "some earlier chat"
date=2023-06-10

FactEvent → SourceSpan → RawTurn is a foreign-key chain. When the model asserts something about the user, there is a row explaining why.

Facts expire. SodaMem keeps four time axes — when the event happened, when the fact was true, when it was said, when it was stored. "I moved to Chicago last year" and "I'm moving next year" are different rows, and a fact that stopped being true stops coming back. Corrections are ADD-only: a new version plus a SUPERSEDES edge, never an in-place rewrite.

The engine is benchmarked and the answers are published.

benchmark score
LongMemEval-S 92.8% (464/500) 500 answers + 8,427 evidence rows, re-gradable with any judge
LoCoMo 86.88% (1338/1540) end-to-end QA, LLM-as-judge

Those are SodaMem's numbers — the engine this plugin talks to, not the plugin itself.

Why not the MCP bridge?

SodaMem already has an MCP integration for dsh, in the main SodaMem repo (integrations/deepseek-harness/). It exposes memory as tools, which means the model has to choose to call them — and on most turns it simply doesn't. The strongest thing SodaMem offers, the zero-LLM GET /v1/context evidence block, ends up left to the model's discretion.

MCP cannot fix that. A tool is pull-only, and nothing in the protocol lets a server contribute to the prompt or observe a turn closing. This plugin uses the harness's own seams instead — system-prompt/assemble for recall and agent/turn-stopping for retain — so both happen unconditionally.

MCP bridge This plugin
Recall model calls a tool, if it decides to every turn, automatically
Retain model calls a tool, if it decides to every closed turn, automatically
Model can skip it yes no
Costs tool-schema space yes no

Do not run both against the same store. They would recall the same facts twice and ingest every turn twice. Pick one.

Requirements

  • Node >= 22 (the harness requires it; the plugin uses AbortSignal.any)
  • A running SodaMem daemon — see below

Install

dsh plugin --profile tui add dsh-plugin-sodamem

That is all that is needed. The package ships a dsh.bundle manifest pointing
at cordis.patch.yml, so dsh adds the plugin to the
profile's bundle list and composes its row — with working defaults — into the
profile tree. Confirm it landed:

dsh --profile tui --dump-config | grep -A6 'id: sodamem'

Start the daemon first (once per machine):

sodamem daemon ensure          # defaults to http://127.0.0.1:8000

Fact extraction needs LLM credentials on the daemon side. Put SODAMEM_LLM_PROVIDER / SODAMEM_LLM_API_KEY / SODAMEM_LLM_MODEL in the daemon's environment or .env. Without them recall still works, but every retain will be accepted and then fail during extraction.

Configure

The bundled cordis.patch.yml ships defaults that boot (apiUrl
http://127.0.0.1:8000, userId default). To change them, override the row
in your own profile cordis.patch.yml, which applies after every bundle
layer:

# $DSH_HOME/profiles//cordis.patch.yml
- id: sodamem
config:
apiUrl: 'http://127.0.0.1:8000'
apiKey: 'dev'
userId: 'your-user-id'
tokenBudget: 1200

A patch replaces the targeted row's whole config rather than merging into
it, so restate every key you want to keep.

Without installing as a bundle, the same row can be inserted ad hoc:

npx @deepseek-ai/dsh web --patch ./sodamem-plugin.patch.yml

Config fields

There are four, and they are all connection or scope facts.

field required default what it is
apiUrl yes — Origin of the SodaMem daemon
apiKey yes — Sent on every request. Any non-empty string works when the daemon runs with auth disabled — there is no magic fallback
userId yes — The SodaMem user_id every read and write is scoped to
tokenBudget no 1200 Token budget for the recalled evidence block

There is deliberately no switch that turns recall or retain on or off, and no strategy selector. Auto-injection is the entire point of the plugin; a knob to disable it would just be a slower way to use the MCP bridge.

session_id on retain is the agent's id (in dsh, an agent and its session share one identity). agent_id is deliberately not sent — it would be the session id, which would narrow retrieval and fragment recall across sessions.

Remote mode only

The plugin talks HTTP to a daemon. It has no data-root option and imports nothing that can open a store locally, and that is a deliberate constraint rather than an unfinished feature.

Two processes writing one SODAMEM_DATA_ROOT corrupt it — per-user SQLite without cross-process WAL is not safe under concurrent writers, which is why the daemon is pinned to a single worker (SodaMem mcp_server/README.md and ADR 0001 §2). A plugin loaded inside an arbitrary harness process is the worst possible candidate for being that second writer — you would not know how many of them are running. So there is exactly one writer, the daemon, and everyone else is a client.

When SodaMem is down or slow

A SodaMem problem is never a dsh problem. Every call is wrapped so that no error, rejection, timeout, or abort escapes into the turn.

Recall deadline 1500 ms
Retain deadline 5000 ms
Daemon unreachable, erroring, slow, or returning junk recall contributes nothing; the turn proceeds normally
Turn cancelled in-flight SodaMem requests are aborted with it

The deadlines cover the whole call, headers and response body alike, so a daemon that answers 200 and then stalls mid-body cannot hang a turn.

Recall fires once per question, not once per prompt assembly — a tool loop that takes six steps still issues one GET /v1/context. Steering mid-turn is a new question, so it earns its own recall.

Retain ingests only what a human or the model actually said. Tool results and the harness's runtime-context snapshot are excluded — the snapshot is where this plugin's own recalled evidence lives, and ingesting it would feed the store its own output back on every turn.

The one thing to know: when recall misses its deadline, the turn proceeds without memory and nothing surfaces to the user. The plugin logs a warning (ctx.logger.warn) on every degraded turn, and that log is the only signal you get. See the performance note below.

On load the plugin also issues a cheap warm-up request, so the daemon's lazy store open — measured at ~630 ms against a ~130 ms steady state — is paid before your first question instead of by it. Nothing waits on that warm-up, and it is harmless when no daemon is running yet.

Performance

Measured on a real 1000-fact store (auth on, single-worker daemon, loopback, one machine, chromadb 1.1.1, chroma schema verified at 9 sysdb migrations). Full method, caveats, and reproduction steps: NOTES-latency.md (shipped in the package too).

> Retraction. An earlier version of this section claimed cold start returns HTTP 500 in 10 runs out of 10 from a Chroma panic, and that warm steady state was p50 17 ms. Both are withdrawn. They were measured against a store whose chroma schema had been migrated by a different chromadb version than the one reading it — a defect of the test machine, not of the daemon or the plugin. The 17 ms figure was that broken store answering with vector search switched off, so it understated real warm latency by roughly 7x. Full account, including the old numbers: NOTES-latency.md, and a summary in CHANGELOG.md.

  • Cold start costs extra, but it succeeds. The daemon opens a user's store lazily. Across 3 daemon restarts the first request returned HTTP 200 every time, with full vector routes and no degraded retrieval (0 degraded / 17 citations, 3/3). It costs about 630 ms against a ~130 ms steady state; the second request is already warm. The plugin absorbs that one-time cost with a fire-and-forget warm-up at load (src/warmup.ts), so it lands before the user's first question rather than on it.
  • Warm, steady state: p50 130 ms (min 101, p95 164, p99 186, max 296 — 200 sequential requests, six store-relevant queries, token_budget 1200). That is what auto-injection adds to time-to-first-token once the store is open. It is the zero-LLM path, so it does not grow with model spend.
  • Multi-client is the caveat, and it is smaller than previously stated — but do not read it as comfortable. The daemon runs one worker by design, and /v1/context latency grows near-linearly with concurrent clients: median 128 / 211 / 361 / 672 ms at concurrency 1 / 2 / 4 / 8. At concurrency 8 the worst of 40 requests was 732 ms on an otherwise idle machine, and 986–1268 ms across five runs on a loaded one (load avg 14, where sequential p50 was 197 ms rather than 130 ms). So the margin against the 1500 ms recall deadline is somewhere between ~1.2x and ~2x depending on what else the box is doing — real headroom, not an order of magnitude, and the loaded machine's worst run came within 16% of the deadline. The withdrawn figures put it within 10% of the deadline on the broken store; the correction is smaller than that retraction alone would suggest.

Read the concurrency numbers as a shape, not as absolute milliseconds. The probe runs five rounds per level, which does not warm the BM25 index cache the way 200 sequential requests do, and its right-hand column is the worst of n rather than a p99. What reproduces across machines is the near-linear queueing; what moves is the millisecond.

So: the shape is unchanged — enough concurrent clients on one single-worker daemon and recall will start silently dropping. Nothing measured here reaches that point at 8 clients, on either machine. That is a property of the daemon's read path, not of this plugin; auto-injection is what makes it reachable, by turning an occasional tool call into a per-turn one. The numbers behind this, and the caveats on each, are in NOTES-latency.md.

Development

npm install
npm run typecheck
npm test          # no live daemon required; HTTP is mocked at the fetch boundary
npm run build     # dual ESM/CJS into dist/

npm run test:integration   # real dsh runtime + real daemon; not run by CI

npm run test:integration loads the plugin into a real dsh runtime — real
Cordis Context, real session store, real system-prompt registry, real agent
loop — and drives real turns against a running SodaMem daemon. It stubs only the
LLM adapter. See test-integration/README.md for
how to start the daemon.

The unit tests cannot prove the plugin works inside the loop: they mock the
Cordis registration boundary, so they cannot see ordering. Treat the integration
suite as the gate.

License

Apache-2.0. See LICENSE and NOTICE.

常见问题

7 问
答案由本站依据条目字段整理,不引用上游原文
dsh-plugin-sodamem 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add [email protected]` 即可。对应的 npm 包名是 `dsh-plugin-sodamem`。

dsh-plugin-sodamem 的验证等级是什么意思?

L5 · 运行验证通过。在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来

dsh-plugin-sodamem 安全吗?

低风险。vet 静态分析未发现可疑行为,判定为干净(clean)。

dsh-plugin-sodamem 支持哪些 DSH 版本?

上游记录的兼容版本包括 0.2.0-rc.2、0.1.7-rc.2、0.1.7-rc.1、0.1.7-alpha.2、0.1.6-alpha.2、0.1.6-alpha.1、0.1.5-rc.2、0.1.3-alpha.2。版本较多,只列出前 8 个。

dsh-plugin-sodamem 用的是什么许可证?

上游标注为 Apache-2.0。商用或二次分发前请到仓库确认许可证原文。

dsh-plugin-sodamem 有哪些功能?

自动回忆证据、自动回写会话、事实可溯源、事实自动过期、零模型调用。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

记忆与知识
按星标排序,可作替代方案

ruflo

ruflo

L3 · 安装规范通过 7.4 万 星

OpenViking

OpenViking

面向 DeepSeek Harness 的 OpenViking 记忆与上下文插件:pre-step 自动召回与画像注入、会话捕获、`vik

L3 · 安装规范通过 3.9 万 星

WeKnora

WeKnora

把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己

L4 · 沙盒安装通过 3.3 万 星

distilly

distilly

Distilly — Distill how they think into reusable Skills for any Agent o

L4 · 沙盒安装通过 2.5 万 星

EverOS

EverOS

L4 · 沙盒安装通过 1.3 万 星

MemOS

MemOS

L4 · 沙盒安装通过 1.2 万 星

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 2026-10-08。