DSH Third-Party Long-Term Memory Plugin (Unofficial) ==================================================== An unofficial, third-party long-term memory plugin for DeepSeek Harness (DSH). Package id: dsh-thirdparty-memory. 中文名:DSH 第三方长期记忆插件(非官方)。 > Not affiliated. This is an independent open-source project. It is not associated with DeepSeek, Doubao, or their official teams, and carries no authorisation or endorsement from them. Product and company names are used only to describe compatibility. One master switch, automatic extraction, five kinds of memory, a review inbox, keyword-relevant injection, a local memory page, and a single-file Windows manager — with English / 简体中文 / 繁體中文 UI. > Docs: this file is the English root. Translations: 简体中文 (README.zh-CN.md) · 繁體中文 (README.zh-TW.md). > Every document also ships as plain text: README.txt, README.zh-CN.txt, README.zh-TW.txt. > Deep dive: docs/tutorial.md (also as .txt, with zh-CN / zh-TW versions in docs/). Platforms : DSH Desktop (MSIX) · DeepSeek Harness portable (Electron) · CLI `dsh web` Runtime : Node.js 18+ (the exe ships its own Node 24) Storage : one local JSON file — no database, no vector store, no cloud, no telemetry License : MIT ------------------------------------------------------------------------ Why --- AI conversations fail at memory in two opposite ways: it remembers too little (you repeat your preferences, project paths and past mistakes in every new chat) and too much (everything gets stuffed into the system prompt, burning tokens and confusing the model with irrelevant facts). dsh-thirdparty-memory splits the difference: memories are classified, injection is relevance-filtered, and anything the AI infers about you has to pass a review inbox before it can ever reach the prompt. ------------------------------------------------------------------------ Features -------- * Four categories global (always injected) · project (activates with its project) · persona (always injected) · ephemeral (this session only) · plus general * Keyword-relevant injection Only entries matching the current message enter the prompt; the rest collapse into a numbered index. Typically 6.5 KB → 1.2 KB on unrelated questions. * Multi-topic coverage Mention several things in one sentence and each topic gets its own representative entries, so one hot topic cannot eat the whole budget. * Explicit recall Say "extract all memories about X" to drop the relevance threshold and get the whole batch (the budget widens too). * Review inbox Auto-extracted persona facts wait in the inbox; they are injected only after you accept them. * Self-directed writing The agent judges what is worth keeping (pitfalls, conclusions, personal facts) and writes it without asking — judgeMode: model (default). * Update, don't duplicate The agent searches first and updates the existing entry: one fact, one entry, always the latest text. * [全局] prefix Any memory whose text starts with [全局] / [global] is injected every turn. * Token dashboard See exactly how many bytes/tokens each section costs, with warnings when always-on memories crowd the budget. * Prompt preview One click shows the exact text that would be injected into a new chat. * Single-file manager dsh-memory-manager.exe (~34 MB) embeds Node + everything; double-click, tray icon, no URL to remember. * Zero runtime deps The server is node:http; there is nothing to npm install. ------------------------------------------------------------------------ The five kinds of memory ------------------------ * 🌍 global Meaning: Language preference, hard prohibitions, workflow rules When injected: every turn * 📁 project Meaning: Project-bound paths, pitfalls, scripts, specs When injected: only while that project is active (named in the message, or currentProject) * 👤 persona Meaning: What you care about, what annoys you, taste, habits When injected: every turn * ⏳ ephemeral Meaning: Scratch context for this conversation When injected: same session only * 📝 general Meaning: Everything else When injected: keyword relevance Each entry also carries priority (high must follow / medium recommended / low reference) and an optional TTL (never / N days). > **Project memories are a gate and a filter**: a project entry becomes eligible when its project is active, and is still keyword-filtered before injection. Activating a project never dumps all of its entries into the prompt. What a persona entry has to look like A memory system that profiles its user in the third person turns creepy fast. What separates a usable persona entry from a creepy one is not tone, it is evidence — a well-formed entry has four properties: * dated What it means: it carries the date of the observation Why it matters: an undated observation cannot expire, and persona notes age * scene-bound What it means: it names what actually happened Why it matters: a scene can be confirmed; a character trait cannot * anchored What it means: it keeps their own words or a concrete action Why it matters: paraphrasing is where invention enters * one line of reading What it means: judgement comes last and stays short Why it matters: the evidence stays intact and the interpretation is clearly separate A badly formed entry has the opposite profile: adjective-first, undated, scene-free, nothing the reader could confirm or deny. A file full of those is what makes a person ask "why are you keeping notes on me?" Template (structure only, no content): YYYY-MM-DD — "" — . If no scene and no quote come to mind, write nothing — an empty persona section beats an invented one. ------------------------------------------------------------------------ Install ------- 1. Manager exe (easiest) Run dsh-memory-manager.exe. The first launch asks for the UI language (English / 简体中文 / 繁體中文), extracts the bundled runtime into %LOCALAPPDATA%\dsh-thirdparty-memory\, starts the memory page and opens it in your browser. A tray icon stays around: Open memory page · Copy address · Storage location… · Open storage folder · Change port… · Restart/Stop service · Attach to DSH… · Language · Quit dsh-memory-manager.exe open the page, stay in the tray dsh-memory-manager.exe --install attach the plugin to every detected DSH profile dsh-memory-manager.exe --start / --stop / --restart / --status dsh-memory-manager.exe --port 7900 custom port (refuses if the port is taken) dsh-memory-manager.exe --store D:\dsh-mem custom storage folder (rules below) dsh-memory-manager.exe --lang zh-CN switch UI language 2. Script powershell -ExecutionPolicy Bypass -File .\attach.ps1 # all detected profiles powershell -ExecutionPolicy Bypass -File .\attach.ps1 -CreateWeb # create a missing web profile too powershell -ExecutionPolicy Bypass -File .\attach.ps1 -ProfileDir "C:\Users\you\.dsh\profiles\web" powershell -ExecutionPolicy Bypass -File .\attach.ps1 -DataFile "D:/dsh-mem/memory.json" 3. Manual (four steps) For a profile directory such as %APPDATA%\com.yeagoo.dsh-desktop\harness\profiles\web: 1. mklink /J "\node_modules\dsh-thirdparty-memory" "" (or copy the folder) 2. add "dsh-thirdparty-memory" to dsh.profile.bundles in the profile's package.json 3. append to cordis.patch.yml: - id: thirdparty-memory name: dsh-thirdparty-memory config: enabled: true judgeMode: model inbox: true 4. give the plugin its peer: junction \node_modules\@deepseek-ai\dsh-tools → the host's @deepseek-ai\dsh-tools Restart DSH. Bundles are read at boot only. Afterwards Settings → Plugins lists dsh-thirdparty-memory, and the memory page is up at . ------------------------------------------------------------------------ Daily use --------- You: remember: → stored immediately (explicit request), no review needed You: [全局] → injected on every turn from now on; global entries are the priciest bytes You: , then → only the A and B entries are injected; everything else collapses into the index You: extract every memory about → explicit recall: relevance threshold off, budget widened, whole batch delivered You: forget entry 3 / update entry 9 to: → remember remove / remember update; numbering is shared with the page Nothing to type for persona facts: the agent applies the four properties above by itself (judgeMode: model) and only records an entry once it has a date, a scene and your own words. If a note is wrong, delete it on the memory page — every deletion asks for a second confirmation. ------------------------------------------------------------------------ The memory page --------------- (served on 127.0.0.1 as well) * 🧠 Memory Hub What it does: All entries with category filters, pin/unpin, delete (two-step confirm); click an entry → workbench drawer * 📥 Inbox What it does: Auto-extracted persona facts; accept / edit / reject, individually or in bulk * 📊 Token Dashboard What it does: Byte/token split per section, budget warnings, library KPIs * 🔍 Search What it does: Keyword search over content, tags and project * ⚙️ Settings What it does: Master switch, auto extraction, who decides what to remember, index on/off, injection parameters, language, export JSON * 👁 Prompt preview What it does: The exact prompt a new chat would receive ------------------------------------------------------------------------ Configuration ------------- Two layers, later wins: cordis.patch.yml (deployment) → memory page settings stored in memory.json. * enabled Default: true Meaning: Hard switch. Off = no injection, no extraction, add fails. * judgeMode Default: model Meaning: model = the agent decides what to remember · rules = built-in regex fallback · off = never auto-record * autoExtract Default: true Meaning: Enables rule extraction when judgeMode: rules * inbox Default: true Meaning: Rule-extracted persona facts require review * injectMode Default: relevant Meaning: relevant = keyword-selected · all = everything * maxBytes Default: 8192 Meaning: Injection byte budget * maxRelevant Default: 6 Meaning: Max matched entries per turn * perCluster Default: 2 Meaning: Entries per topic when several topics appear * minScore Default: 6 Meaning: Relevance threshold (higher = stricter) * recallMaxBytes Default: 16384 Meaning: Widened budget for explicit recall * maxRecall Default: 40 Meaning: Max entries returned by explicit recall * showIndex Default: true Meaning: Include the numbered index of unselected entries * indexChars Default: 18 Meaning: Title length in the index * currentProject Default: "" Meaning: Active project name (project entries become eligible) * dataFile Default: "" Meaning: Memory file path, empty = /data/memory.json * pageServer / pageHost / pagePort Default: true / 127.5.0.1 / 7891 Meaning: Memory page process Storage rules The manager enforces them whenever you change the folder (Storage location… or --store): 1. the drive must exist; 2. every folder name must be ASCII (A-Z a-z 0-9 space _ - .); 3. the target folder must be empty (or already your current store); 4. a bare drive root is refused. If the old folder still holds memories the manager asks copy them over? — Yes copies, No switches only, Cancel aborts. After a switch, dataFile is written into every attached profile's cordis.patch.yml, so plugin and page keep reading the same store. ------------------------------------------------------------------------ Data ---- One JSON file (memory.json, version 2): { "version": 2, "entries": [ { "id": "mem-xxxx", "content": "", "category": "global", "project": "", "priority": "high", "tags": [""], "source": "user", "status": "active", "pinned": true, "expiresAt": null, "sessionId": "", "createdAt": "2026-01-01T00:00:00.000Z", "updatedAt": "2026-01-01T00:00:00.000Z" } ], "settings": { "enabled": true, "lang": "en" } } status: active · pending (inbox) · rejected. Version-1 files migrate automatically (a [全局] prefix becomes category: "global"). ------------------------------------------------------------------------ HTTP API -------- * GET Path: / Purpose: memory page * GET Path: /api/state?q= Purpose: state + entries + dashboard * GET Path: /api/export Purpose: download JSON * POST Path: /api/entry/add · /update · /delete Purpose: entry CRUD (one delete at a time, by design) * POST Path: /api/inbox · /api/inbox/bulk Purpose: accept / reject * POST Path: /api/settings Purpose: write user-layer settings ({reset:true} restores defaults) * POST Path: /api/preview Purpose: render the injection for a given q Loopback only; POST requires application/json, which blocks cross-site form posts. ------------------------------------------------------------------------ Troubleshooting (short list — full table in the tutorial) --------------------------------------------------------- * Nothing happens after install Cause / fix: DSH was not restarted; bundles load at boot only * Plugin missing from Settings → Plugins Cause / fix: run attach.ps1 again and read its output * Memory page blank Cause / fix: the page process died; run dsh-memory-manager.exe --start * Port 7891 is used by another program Cause / fix: another app owns the port: --port 7900, or Change port… * The agent searches the plugin folder instead of just answering Cause / fix: the plugin was not loaded, so no memory tool existed; restart DSH * Defender flags a scheduled task Cause / fix: never self-install via Task Scheduler (heuristic trojan detection); use the exe's tray or the Startup folder * Memories look like regulations Cause / fix: switch to judgeMode: model and let the agent write persona notes; the inbox shows what it inferred ------------------------------------------------------------------------ Privacy ------- Everything stays in one local JSON file. No network calls, no upload, no telemetry. Memories do enter the model context — never store secrets. Destructive actions require two confirmations, and bulk deletion is intentionally not implemented: delete entries one by one. ------------------------------------------------------------------------ Compatibility ------------- Host Status -------------------------------------------- DSH Desktop (MSIX, desktop 0.2.x) tested DeepSeek Harness portable (Electron) tested (remember list / search verified) CLI dsh web composition verified via --dump-config The plugin deliberately has no schemastery dependency (its Config implements the Standard Schema ~standard contract), so it survives across DSH release lines; the only peer it needs is @deepseek-ai/dsh-tools. ------------------------------------------------------------------------ Build from source ----------------- :: rebuild the single-file manager (needs .NET Framework 4.x csc.exe + a node.exe) powershell -ExecutionPolicy Bypass -File build-single-exe.ps1 :: package release\dsh-thirdparty-memory-.zip (includes a personal-path leak check) powershell -ExecutionPolicy Bypass -File build-release.ps1 :: regenerate the plain-text docs after editing the Markdown node tools/md2txt.mjs README.md README.zh-CN.md README.zh-TW.md docs/tutorial.md docs/tutorial.zh-CN.md docs/tutorial.zh-TW.md ------------------------------------------------------------------------ License ------- MIT — see LICENSE. The bundled Node.js runtime is redistributed under its own MIT license (see docs/NODE-LICENSE.txt).