DeepSeek Harness Plugin

Frog755/dsh-hybrid-memory

Stars ★ 3 Category Memory Added 2026-08-28

Three-layer local memory for DeepSeek Harness: L1 snapshot memory (MEMORY.md/USER.md) read on demand through the memory_* tools + L2 searchable knowledge base (facts + SQLite FTS5, Chinese search via sliding-window tokenization) + L3 import from Hermes/Claude Code/Codex/WorkBuddy and from approved Agent Hub documents (memory/global, memory/projects, accepted decisions) with content-hash dedup. v0.2.0 removed every automatic injection: memory enters the context only when the model calls one of the 12 memory_* tools, and data stays on the local drive.

Install

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:Frog755/dsh-hybrid-memory

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

Hybrid memory plugin for DeepSeek Harness (DSH) — combining Hermes-style frozen-snapshot memory (L1) with a searchable knowledge base (L2) and multi-tool import (L3).

Why

  • Hermes-style memory (MEMORY.md / USER.md): lightweight, token-cheap, prefix-cache friendly, but not searchable and unmoderated.
  • Noema-style knowledge base: searchable, importable, explainable, but needs a separate server and rewrites the prompt on every recall.
  • dsh-hybrid-memory takes the best of both:
Layer Inspired by What it does
L1 snapshot Hermes MEMORY.md / USER.md, read on demand — memory enters context only when the model actively calls a memory_* tool (e.g. memory_recall); char-limited (model-independent)
L2 knowledge base Noema facts/ one-fact-per-file + node:sqlite FTS5 index + entity extraction; on-demand memory_recall / search / browse
L3 import Noema Import existing memories from Hermes / Claude Code / Codex / WorkBuddy with a content-hash ledger for dedup

Data location (important)

Memory data lives on the D drive, never on C:

D:\Develop\DeepSeek Harness\memory\
├── MEMORY.md        ← L1 agent notes (environment facts / project conventions / tool quirks)
├── USER.md          ← L1 about the user (preferences / communication style / habits)
├── facts/           ← L2 one fact per file (human-readable Markdown, active state)
├── pending/         ← review queue: content saved with review=true lands here until accepted
├── index.db         ← L2 SQLite FTS5 index
└── imports.json     ← L3 import dedup ledger

The default root can be overridden with the DSH_HYBRID_MEMORY_ROOT environment variable.

Hermes import path: the plugin probes for the Hermes memory location automatically — HERMES_HOME env var first, then common install paths (D:\Develop\hermes, ~/.hermes, ~/hermes) — and uses the first one that contains a memories/ directory.

Install

# from npm
dsh plugin --profile web add @frog755/dsh-hybrid-memory@latest

# or local development (source directory)
dsh plugin --profile web add link:D:\Develop\DeepSeek Harness\projects\dsh-hybrid-memory
dsh web

A restart of DSH is required on first install (a new plugin must enter the startup tree); afterwards hot reload works.

Model tools (12)

Tool Layer Purpose
memory_add L1 Add a durable snapshot entry (memory = agent notes / user = about the user)
memory_replace L1 Replace a snapshot entry by title
memory_remove L1 Remove a snapshot entry by title
memory_remember L2 Save a knowledge-base fact (default auto-accept; review=true routes to the review queue)
memory_search L2 FTS5 + entity-weighted full-text search
memory_browse L2 Browse the knowledge-base catalog / filter by tag
memory_recall L1+L2 Fused recall: snapshot + search results packed under a token budget
memory_import L3 Import memories from Hermes / Claude / Codex / WorkBuddy
memory_import_agent_hub L3 Import only approved Agent Hub documents: memory/global, memory/projects and accepted memory/decisions
memory_status admin Data root, char usage, fact count, pending count, ledger size
memory_review_list / memory_review_decide review List / accept / reject / edit pending candidates

How it works

  • On-demand, zero context overhead: neither L1 nor L2 is injected into the conversation (no systemPrompt.section residency, no pre-step recall, no skill-attached memory since v0.2.0); memory enters context only when the model actively calls a memory_* tool.
  • Char limit, not token limit: L1 caps (agent 4000 / user 2000 chars) are model-independent, consistent across models.
  • Chinese search: FTS5's unicode61 does not tokenize Chinese; the plugin pre-tokenizes with a 2-char sliding window before indexing, so memory_search matches by word.
  • Threat scan: written content is checked for prompt injection / exfiltration / dangerous instructions and rejected on hit.
  • Atomic writes + drift detection: files are written via temp file + rename; if the on-disk content was externally edited into an invalid structure, writes are rejected and a .bak snapshot is kept.
  • Review queue: default auto-accept; when review=true is passed, facts land in pending/ (file + SQLite status=pending); memory_review_decide(accept) moves the Markdown to facts/ and flips it active, edit rebuilds the FTS index.

On-demand memory access (no auto-injection)

The plugin performs no automatic injection — the L1 snapshot is no longer frozen into the system prompt, and the agent/pre-step first-step/trigger-word recall and the tools/post-execute skill-attached memory were all removed in v0.2.0. Memory enters context only when the model decides it needs it and actively calls a memory_* tool:

  • Search the knowledge base: memory_search / memory_browse / memory_recall (fuses L1 snapshot + L2 retrieval)
  • Check status: memory_status (data root, char usage, fact/pending counts, ...)

The trade-off: zero memory overhead in the context and no [memory-injection] tags; the cost is that memory does not appear automatically if the model forgets to call a tool.

HTTP endpoints

The plugin also exposes two optional HTTP endpoints on the DSH web server:

  • GET /__hybrid-memory/status — status JSON (data root, L1 char usage, L2 fact/pending counts, ledger size)
  • POST /__hybrid-memory/import — trigger an import with an optional { "sources": ["hermes", ...] } body

Compatibility

  • DeepSeek Harness (Cordis-based), web profile
  • Node.js 22.5+ — the plugin uses the built-in node:sqlite module (DatabaseSync), no native dependencies
  • Peer dependencies: @deepseek-ai/dsh-llm, @deepseek-ai/dsh-tools

Privacy

All memory data stays local. The plugin writes only to the configured data root (default D:\Develop\DeepSeek Harness\memory, overridable via DSH_HYBRID_MEMORY_ROOT). Nothing is sent to any external service. L1 snapshots and L2 facts enter the context only on demand, when the model actively calls a memory_* tool — no automatic injection. No telemetry, no network calls.

Development

# Core logic (no host dependency needed)
node --test tests/core.test.js            # 32 tests covering L1/L2/L3 core logic

# Agent Hub projection (first two cases need no host dependency; the third imports the plugin)
node --test tests/agent-hub-source.test.js

# Smoke test: really loads the plugin and asserts event/tool registration (needs @deepseek-ai/* resolvable)
node --test tests/smoke.test.js

The @deepseek-ai/* devDependencies are link:ed to a local DSH checkout, so only a clone on a machine with DSH installed can run the cases that import the plugin. On a bare clone (or CI) those cases skip instead of failing.

Screenshots

Plugin entry in the DSH settings (plugin list) Architecture
plugin list architecture

License

MIT

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.