Repository navigation
Releases: kittitys/dsh-mem0-memory
Release list
v0.1.6 — DSH 0.2.x session-format support
DSH 0.2.x session-format support (v4 transcripts)
This release fixes four silent failures that appeared after upgrading to DSH 0.2.x. Two of them made the plugin quietly stop working for real users.
1. New sessions were invisible to the importer
g1-session-parser.mjs only looked for session.jsonl.zstd. DSH 0.2.x writes session.v4.jsonl.zstd (and keeps v3/legacy copies), so every session created after the upgrade was skipped: imports reported "no matching events" while conversations kept happening.
Now the parser picks the newest session*.jsonl(.zstd) per session directory (latest mtime wins, higher format version breaks ties), so both generations of transcripts are read.
2. Recall blocks were being re-ingested as user messages
In v4 the message source changed from the catch-all {kind:"plugin", plugin:"x"} to producer-owned kinds (plugin:<name>, time-context, user-approval, agent-instructions, …). The old blacklist missed all of them, so the <relevant-memories> block this plugin injects — and every other system injection — was treated as a real user message and fed back into the memory store (a self-pollution loop).
The filter is now an allowlist: only kind:"user" (or a message with no source at all, for old logs) counts as a real user message. Everything else is dropped and counted, and unknown kinds raise a warning so future channels are visible.
3. Workspace exclusion on the import side matched the wrong path
projectKey is a lossy encoding of the working directory: : / \ become -, but existing - are not escaped. Any path containing a hyphen (OKR-DSH-Trial-20261024) was decoded into garbage, so the ledger lookup and the 0_ prefix check both failed silently.
The parser now reads the absolute cwd from the session header and uses that as the authoritative workspace identity; the lossy decode is only used for display and as a fallback. The basename fallback was removed because under hyphenated paths it could match an unrelated workspace (a false exclusion is harder to notice than a false inclusion).
4. Recall-side exclusion never fired
The plugin read agent.session.cwd, which does not exist in DSH, so the exclusion check always saw an empty cwd and returned "not excluded". It now uses session.header.cwd and falls back to ctx.workingDirectory.get(session).
Also new: exclude by workspace title
Workspace exclusion now honours three markers, matching the importer: a directory segment starting with 0_, an entry in excludeWorkspaces, and — new — a workspace title in $DSH_HOME/storages/workspace.json starting with 0_. That means renaming a workspace to 0_… in the DSH UI is enough to stop recall there; the directory name does not have to change.
Compatibility
All four changes are backward compatible with 0.1.x: legacy transcript filenames remain in the candidate list, and messages without a source field are still treated as real user messages. The mem0 server and the import CLI are untouched.
Verified against DSH 0.2.1-rc.2 with real 0.2.x transcripts: candidate sessions 109 → 119, a day that previously produced "no matching events" now yields batches, one v4 session drops from 26 turns / 43 messages to 17 turns / 34 messages once injections are filtered, and the exclusion matrix passes all six cases (directory 0_, title 0_, excludeWorkspaces entry, workingDirectory fallback, and a normal workspace still recalling).
Upgrade is recommended for anyone running DSH 0.2.x. See CHANGELOG.md for the full (Chinese) detail.
v0.1.5 — DSH 0.2.x support (0.2.1-rc.2)
DSH 0.2.x support (0.2.1-rc.2 verified)
This release makes the plugin installable and functional on DSH 0.2.x.
What was wrong
- Install was rejected. The
@deepseek-ai/dsh-agent-looppeer range was^0.1.0-rc.6, which means>=0.1.0-rc.6 <0.2.0. DSH 0.2.1 shipsdsh-agent-loop@0.2.1-rc.2, so its new compatibility check refused the install and rolled the profile back. - Even an exempted install would break every turn. DSH 0.2.x introduced session format v4, whose message validation rejects the catch-all source wrapper
kind: "plugin"and requires a producer-owned kind. The recall injection still used{ kind: "plugin", plugin: "dsh-mem0-memory" }, so each injected turn failed withformat v4 message requires a producer-owned source kind.
What changed
peerDependencies["@deepseek-ai/dsh-agent-loop"]:^0.1.0-rc.6->^0.1.0-rc.6 || ^0.2.1-rc.2(bounded on both ends on purpose: this plugin writes session events, so an unbounded*/>=would silently accept future breaking majors).- Injected recall messages now carry
source: { kind: "plugin:dsh-mem0-memory", form: "recall" }— the same producer kind the v3→v4 migration assigns to unknown plugins, so new records and migrated history look identical. - No changes to the mem0 server, the G1 session parser, or the import CLI.
Compatibility
One build runs on both lines: DSH 0.1.x only requires a non-empty source.kind for user/message (the strict kind: "plugin" check applies to system/message only), and 0.2.x accepts the producer-owned kind. Verified on DSH 0.2.1-rc.2: install accepted, recall injected, session closable and reopenable, v4 transcript event shape correct. >= 0.3.0 is intentionally excluded — those majors need re-verification first.
See CHANGELOG.md for the full (Chinese) detail.
v0.1.4
autoStartServer: when DSH starts, the plugin probes the mem0 server /health (3s timeout) - if not running, it spawns the server once (detached, survives DSH exit). Already running = untouched. One spawn per DSH process max, failures are WARN-only (no retry loop). New config: autoStartServer (default true), pythonPath (optional).