dshbase

插件目录 / Storage / dsh-mem

dsh-mem

已验证 · 实测可装 Jelee0145

✓ 持续维护 基于 5 个官方 DSH 包 纯 TypeScript

查看 GitHub ↗ ← 返回插件目录

3Stars
0Forks
0未关闭 issue
TypeScript语言
2026-08-14最近推送
跨平台平台

功能简介

跨会话长期记忆:JSON文件存储,提供记忆增删查列工具,可安装为dsh包

我们的评价
可用 — 实测通过,早期项目

跨会话长期记忆:JSON文件存储,提供记忆增删查列工具,可安装为dsh包 实测能干净安装、正常启动。早期项目,但功能可用。

「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。

README

dsh-mem — cross-session memory for DeepSeek Harness

English | 中文

An out-of-tree bundle plugin for DeepSeek Harness (dsh) that implements a complete capability seam — Service Definition + Service Provider + Consumer. It gives agents durable long-term memory shared across every session: the memory_save / memory_recall / memory_forget / memory_list tools persist facts, preferences, and decisions to $DSH_HOME/memory/memory.json.

Install

Install from the npm registry (published as dsh-mem):

dsh plugin --profile <name> add dsh-mem

dsh plugin add is the dsh way to install a plugin: it resolves the package from npm (via pnpm) into the profile and registers its bundle layer. Do not use npm install dsh-mem — that installs the package as a plain dependency without activating any profile layer.

From git instead (runs the package's self-contained prepare build; the first install asks you to allow the build in the profile's pnpm-workspace.yaml):

dsh plugin --profile demo add github:Jelee0145/dsh-mem

Or from a local checkout:

dsh plugin --profile demo add ./dsh-memory

Verify the composed layer without booting, then boot:

dsh --profile demo --dump-config   # expect a "# == dsh-mem" layer with memory / tool-memory rows
dsh --profile demo                 # new sessions can call the memory_* tools

Uninstall: dsh plugin --profile demo remove dsh-mem.

To disable without uninstalling (hot-reloaded, no restart), disable the rows in the profile's own cordis.patch.yml:

- id: memory
  disabled: true
- id: tool-memory
  disabled: true

Memory data is never touched by uninstall; it lives in $DSH_HOME/memory/memory.json (default ~/.dsh/memory/). Back it up or delete it separately if you want to clear it.

The capability seam

Role Module Mounted row Notes
Service Definition src/memory.ts (dsh-mem/memory) abstract MemoryService declaring the ctx.memory contract and types; loading it directly fails loud
Service Provider src/provider.ts (dsh-mem/provider) memory MemoryFile extends MemoryService; atomic JSON-file persistence
Consumer src/tool.ts (dsh-mem/tool) tool-memory function plugin registering the four tools; resolves the service via ctx.get('memory') per call

This mirrors the in-repo ctx.jobs seam (Definition in packages/jobs/jobs, provider in jobs-local, consumer in tool-jobs).

Repository layout

dsh-mem/
├── package.json          # declares dsh.bundle.patch → ./cordis.patch.yml
├── cordis.patch.yml      # bundle layer: inserts memory + tool-memory rows
├── tsconfig.json         # standalone build config (types from npm deps)
├── tsconfig.check.json   # local typecheck against a dsh checkout (optional)
├── README.md             # this file
├── README.zh.md
└── src/
    ├── memory.ts         # Service Definition (default-exports the service class)
    ├── provider.ts       # Provider (default-exports the service class + static Config)
    └── tool.ts           # Consumer (named exports only: name/inject/Config/apply)

Build

npm install      # pulls the dependencies (runtime and compile-time types both come from npm)
npm run build    # tsc emits lib/ (same as the prepare script, run automatically on git installs)

Working beside a dsh checkout, dsh-memory/node_modules/@deepseek-ai/* can be junctioned to the repo packages so local typechecking works without npm install:

pnpm exec tsc -p dsh-memory/tsconfig.check.json   # typecheck only (no emit)
pnpm exec tsc -p dsh-memory/tsconfig.json         # emit lib/

Smoke tests (build first):

node dsh-memory/tests/patch-smoke.mjs     # patch composition over empty and web-like bases
node dsh-memory/tests/provider-smoke.mjs  # provider round-trip: persistence/search/bounds/corruption

Memory entries and storage

Each note is an immutable record of 5–6 fields:

Field Source Meaning
id provider m-<n>; keeps counting across restarts
content model the durable fact as a complete standalone sentence or short paragraph
tags model keywords for filtering; empty strings are dropped
project model the owning project/workspace (e.g. repository name); absent means a global fact that applies everywhere
createdAt / updatedAt provider, stamped automatically epoch milliseconds; the model never supplies the timestamp, and the tool output includes a human-readable createdAtText (ISO 8601)

Stored at $DSH_HOME/memory/memory.json (default ~/.dsh/memory/), e.g.:

{
  "version": 1,
  "nextId": 3,
  "entries": [
    {
      "id": "m-1",
      "content": "Project X uses pnpm workspaces and rejects yarn.",
      "tags": ["project", "tooling"],
      "project": "project-x",
      "createdAt": 1753000000000,
      "updatedAt": 1753000000000
    }
  ]
}

Design notes

  • Why the provider owns a JSON file instead of the ctx.storage seam: dsh's storage rows (storage / storage-json / storage-domain) are mounted by the dsh-web-app bundle, not by dsh-base; an out-of-tree bundle that inserts the same row ids would duplicate them in web profiles, while omitting them leaves ctx.storage absent in headless ones. One self-managed JSON document keeps this plugin zero-dependency on every profile (web / headless / custom). To swap in a ctx.storage.domain backend, subclass MemoryService and point the memory row at it — the tools and contract stay untouched. That is the point of the seam.
  • Durability: every mutation writes memory first, then commits via writeFileAtomic (temp file + atomic rename, 0o600/0o700); nothing is visible before it is durable. All operations (reads included) serialize on one in-process queue, so a read never observes an uncommitted write. Concurrent dsh processes sharing one root are not supported.
  • Document format: { version, nextId, entries }; nextId is persisted so ids stay unique across restarts. A wrong version or a corrupt file fails loud at load — never a silent reset.
  • Model tool contract: search is a case-insensitive substring match on content plus exact tag match; an empty query returns the newest notes. recall/list accept a project filter (case-insensitive exact; global notes never match). Result caps are clamped to the deployment's maxRecallLimit. Oversized content, illegal limits, and malformed ids are rejected at the tool boundary. When to save and what to save is guided by the tool descriptions: project-specific facts must carry project; global facts (e.g. user preferences) omit it; timestamps are provider-stamped and cannot be forged by the model.
  • Dependencies: @deepseek-ai/cordis@^4.0.1 and @deepseek-ai/dsh-*@^0.1.0-rc.6 are published on npm; dsh plugin add installs them into the profile.

Extending

  • Swap the provider: subclass MemoryService, then point the memory row's name at your class in cordis.patch.yml.
  • Add a human command: inject ctx.commands (present in base) and register a /memory-style slash command.
  • Inject memory into a turn: in an agent/pre-step or tools/post-execute listener, call agent.inject() with relevant notes for the next request.
  • Move the storage root: override the whole memory row's config.root in the profile's cordis.patch.yml (a patch replaces the whole config, so restate the keys you keep).

Known limitations

  • Single-process writer: no cross-process lock when two dsh processes share one root.
  • No edit API: updatedAt equals createdAt today; to overwrite a fact, memory_forget then memory_save.
  • No structured schema: content is free text; for fielded facts, agree on a fixed text format with the model.

安装

🧩 让 Agent 自动装(推荐)

装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:

dsh plugin add dshbase-catalog

然后对 agent 说「帮我装 dsh-mem」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包

该插件是 GitHub 源码(未发 npm)——直接从仓库装:

Web profile:

dsh plugin --profile web add github:Jelee0145/dsh-mem

Headless(CLI)profile:

dsh plugin --profile headless add github:Jelee0145/dsh-mem

实测报告

验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。

使用场景

给 agent 持久存储——数据库、文件存储或持久层——让状态跨会话留存。

适合谁

任务需要读写结构化数据并跨运行保留的人。

二次开发建议

存储后端和数据模型是缝——插新数据库、加 schema 或暴露查询工具。

安全:尚未扫描——我们的每日静态扫描将很快覆盖它。

分享徽章

Storage 里更多

浏览全部 7795 个插件 →