lemonmmice/dsh-agent-toolchain--plugins-dsh-memory ↗★ 0
dsh-memory
DSH 长期记忆增强插件:文档索引 + 语义检索 + 跨会话 KV 记忆(agent 工具) 适合需要赋予编程Agent长期记忆与跨会话知识检索能力的任务。
같은 패키지 이름의 다른 저장소
설치
검증된 bundle이 없거나 호환성 검사에 실패했습니다. 먼저 저장소 설명을 읽어 주세요. 전체 README 읽기 ↗
dsh-memory
Long-term memory for coding agents: document indexing + semantic search +
cross-session key-value conventions. Ships as a DeepSeek Harness plugin and
through the MCP server (memory_index / memory_search / memory_save /
memory_recall / memory_forget / memory_status).
What it does
memory_index(path)— index a directory's docs/code into a local vector store. mtime-incremental: files whose mtime is unchanged are skipped; updated files get their old chunks evicted and replaced; chunks of deleted files are removed. Multi-root: indexing directory B never evicts directory A's chunks — eviction judges file existence on disk, not the currently-indexed root.memory_search(query, k)— semantic search (MiniMax embo-01 vectors; falls back to a local character-bigram index when no key is configured).memory_save/memory_recall/memory_forget— cross-session KV conventions, scoped per project (e.g. the project name).
Native vector store
From the monorepo root, build with Rust and the platform linker (Windows: Visual C++ build tools):
npm run build:memory-store
npm run test:memory-native
node scripts/run-tests.mjs dsh-memory
Deploy the whole plugin including bin/ -/memory-store.node.
Consumers do not need Rust. DSH_MEMORY_STORE_NATIVE optionally overrides the
module path. The same adapter is used by DSH and MCP; restart both after deployment.
Windows x64 is validated; Linux GNU/macOS build targets are provided but untested.
Rust caches the vector index, computes dense/sparse similarity, selects stable
top-k hits, indexes ID prefixes and writes JSONL through staged replacement and
.bak backup. The JSONL file remains the source of truth; external changes cause
reloads, while conflicting unflushed batches fail instead of overwriting them.
File embedding results are published as complete files; failed reindexing keeps
the previous complete snapshot. Final flush errors reach the caller.
Local bigram Maps are serialized as objects so new vectors survive restarts. Previously saved empty sparse objects cannot recover lost terms automatically; reindex the source into a new project namespace if affected (unchanged-file mtime skipping otherwise retains the old index). No user index is rewritten on read. See validation and timings.
Hygiene guarantees
- Successful reindexing replaces stale chunks: indexing a changed file replaces all of its
previous chunks after embedding succeeds (chunks are keyed by
file::); indexing a workspace also evicts chunks belonging to files that no longer exist on disk. Failed reindexing retains the last complete snapshot, and search freshness metadata identifies changed/deleted sources. - Secrets never land on disk — and never leave the machine:
memory_saveruns a fail-closed sensitive-string filter (GitHub tokens, OpenAI-style keys, AWS access keys, bearer tokens, private-key blocks, labeled secrets). A hit rejects the save. The index path is screened too: a file whose content trips the filter is skipped before chunking and counted assensitiveSkipped, so it is never embedded — and therefore never sent to an embedding API.
Data & privacy
- Remote embedding requests have a 20-second default timeout (
DSH_MEMORY_EMBED_TIMEOUT_MS), covering both response headers and JSON body reading. Error responses are cancelled without exposing their bodies. - Embedding cache names use SHA-256 over the endpoint, model and input text. Older 32-bit cache files are ignored and retained; subsequent calls populate the new cache without changing stored vectors.
- Everything lives under
~/.dsh/memory/(override withDSH_MEMORY_DIR/DSH_HOME). - Embedding egress: when a MiniMax API key is configured
(
MINIMAX_CN_API_KEYor~/.dsh/.credentials.yaml), indexed chunks and search queries are embedded via the remoteapi.minimax.chatendpoint — i.e. that content leaves this machine. Without a key, embeddings fall back to a local character-bigram index (zero egress).memory_statusreports the active endpoint, so the choice is visible, not implicit.