skepsun/dsh-engram0

dsh-engram

基于符号索引与 pi-esr 理念的 DSH 极简长期记忆插件,通过纯模式匹配自动捕获事件以节省 Token。

AI 分析

核心用途是通过免 LLM 调用的模式匹配自动捕获关键事件,实现低 Token 消耗的长期记忆。适合需要长期上下文记忆且希望节省 Token 的用户。

包名
dsh-engram
版本
0.3.0
许可证
MIT
最近更新
2026年8月23日

安装

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:skepsun/dsh-engram

dsh-engram

English · 中文

Minimalist long-term memory for DeepSeek Harness, distilled from the symbolic-index and pi-esr ideas — with one goal: save tokens.

  • Zero-LLM intake — auto-captures meaningful events from tool results by pure pattern matching (git milestones with a written -m commit message, edits to key files, repeated errors), plus an explicit engram_store. Nothing on the hot path calls a model, and pure plumbing — git push / git stash / silent commits — is deliberately never recorded (see Auto-capture policy below).
  • Symbolic index + progressive disclosure — a compact [ENGRAM] block (default budget 700 chars ≈ 175 tokens; one line per memory) is injected at prompt assembly and frozen per session, keeping the request prefix byte-stable for KV-cache reuse. The agent drills down with engram_recall / engram_detail instead of dumping raw hits into context; recall ranks the in-domain pool with an in-process BM25 pass (TF·IDF with label/phrase boosts plus a gentle time-decay factor — deterministic, zero deps), appends a compact entity-neighborhood table (reusing esr_link: node --rel--> node · conf%) for entity-anchored hits, re-warms the old error entry when a new failure is near-identical (repeat-failure revival: recency + hit climb toward promoteHits so the failure resurfaces instead of piling up), and on zero local hits falls back to DSH's own cross-session full-text index (ctx.sessionQuery, filtered by cwd) instead of building a parallel SQLite index.
  • ESR-lite closure protocolesr_task / esr_close / esr_link give tasks a draft → active → stable lifecycle where stable requires real evidence (artifact / evaluation / memory_ref), surfacing closure gaps instead of letting the agent declare victory without proof. With verifyArtifact on (default), a non-URL artifact is resolved against the workspace (= the session cwd) and must exist on disk — otherwise the task stays ACTIVE with the reason; force:true (or disabling the toggle) skips the disk check, the three gates are still mandatory. The tool and the web forms share one gate (store.evidenceGate), so the two surfaces can never drift.
  • Memory GC (pi-esr constraints) — a scheduled, mechanical, archive-only sweep: TTL-expired memories are archived, over-cap workspaces evict the lowest-value entries, stable tasks past their retention window leave the [ESR] surface, and dangling link edges are dropped. The working set (active task refs, task memories, indexed hits) is never touched, and nothing is hard-deleted — every archived entry keeps its id and stays re-fetchable.
  • Web viewer — a memory browser with benchmark-ish stats and a config card, built entirely on DSH's native settings slots (no third-party UI package).
MIT   ·   node >= 22.19   ·   host-half + browser-half in one package

Why another memory plugin?

Surveys of the existing DSH plugin ecosystem show the recall-bridge, approval-gate, LLM-distillation and vector/graph niches are already crowded. dsh-engram fills the three gaps that matter for token discipline:

  1. No model in the write path — capture is deterministic pattern matching.
  2. No raw text in the prompt — a bounded symbolic index is injected, retrieval stays on demand ("retrieved ≠ injected").
  3. Honest task closure — STABLE cannot be declared without evidence.

DSH already provides cross-session FTS (ctx.sessionQuery), storage (ctx.storageDomain), prompt-injection hooks and settings slots; dsh-engram is a thin composition layer over them, not a re-implementation.

Install

# from GitHub (this repo)
dsh plugin --profile web add github:skepsun/dsh-engram

# once published to npm
dsh plugin --profile web add dsh-engram

# local development (symlink — edits apply immediately)
dsh plugin --profile web add link:/path/to/dsh-engram

Then restart dsh web. Data persists in ~/.dsh/storages/dsh_engram.json.

The npm and GitHub installs below need no manual dependency step: pnpm installs zod and vendors the optional @deepseek-ai/* peers into the plugin's own node_modules, and the CLI auto-registers the plugin into the profile's dsh.profile.bundles. The setup-links step below is only for the link: development workflow, where pnpm deliberately does not install a symlinked directory's dependencies.

A fresh session is required to see the injected [ENGRAM]/[ESR] blocks and the tools; both prompts and the tools registry are assembled per session.

Dependencies for link: installs

A symlinked plugin resolves its imports from its own node_modules, so the host-side dependencies must be present next to the checkout — they are not tracked by git:

cd /path/to/dsh-engram
node scripts/setup-links.mjs     # one command: links the @deepseek-ai
                                 # workspace packages into node_modules AND
                                 # installs zod (reused from the harness
                                 # pnpm store, or via `npm install`)

The script auto-locates the harness checkout at ../deepseek-harness (also works when it sits next to the repo's parent, e.g. E:\deepseek-harness + E:\kototoro_demo\dsh-engram); override with DSH_HARNESS_DIR. Without this step, dsh web boot fails with ERR_MODULE_NOT_FOUND: Cannot find package 'zod' (and would fail on the @deepseek-ai/* peers next). node scripts/setup-links.mjs --check prints the state without writing anything.

What you get in the GUI

After restart, inside the native DSH settings surface:

  • Sidebar "ESR 看板" entry + full-screen kanban — one more row under New Session with a live active-task badge (polled from /overview every 30s across all workspaces). Clicking it opens a full-screen board in the center column: 草稿 / 进行中(gaps) / 就绪(evidence ready) / 已闭环 columns, workspace filter + search, an inline create form, and per-card "补齐证据 → 关闭" closure forms sharing the esr_close gates (artifact + evaluation + memory_refs). A 看板 / 图谱 (board/graph) toggle in the header reuses the full relation graph (esr_node/esr_link force-directed SVG: entity circles + task check badges, drag/zoom/select for relation details), following the workspace filter and refreshed by the same 20s polling. Following the task-board precedent, the entry and the board are DOM-mounted and self-heal (MutationObserver re-inserts on shell re-renders), with cross-panel exclusivity against task-board/ssh (opening one evicts the others; clicking a sidebar session/workspace row hands the center column back to the conversation). The conversation subtree stays mounted underneath and is hidden by html[data-dsh-engram-board-active], so toggling loses no state.

  • Unified task strip above the composer — the conversation dock that DSH ships for its built-in todo tool is taken over (same conversation.input.dock cell / id: todo at a lower priority) and merged into one modern control: the session's current plan (todo_write's todos projection) plus the workspace's persistent ESR tasks (with evidence-gap badges and an inline "补齐证据 → close" form) plus the relation graph rendered as node → relation → node chips with entity/task names resolved. It only shows while there is something to show, stays live with 15s polling, and the built-in plan still renders (without the ESR parts) if the loopback-fenced API is unreachable. A workspace-switcher chip leads the strip: it defaults to following the current session (the tooltip says so), and its dropdown pins the ESR task/relation source to any workspace (✓ marks the active pin; the × or "follow session" entry reverts). Switching refetches immediately and is a pure UI focus change — the model's session context and the per-session frozen injection blocks are untouched.

  • Settings → Engram Memory — a standalone first-class settings section (right after the Plugins section, not a child tab of it). Default "All workspaces" view shows every workspace's memories/tasks/links grouped by workspace (dropdown + prev/next workspace pager; the memory table additionally pages 10 rows per page with a jump dropdown, fixed column widths, 3-line clamped content ellipsis and full text on hover). Overview stat cards (counts by workspace/kind, auto-capture totals, per-workspace [ENGRAM] index token estimate, cumulative GC totals), a searchable / filterable memory table with archive + delete actions, an ESR task board with an inline "new task" form and a per-task "fill evidence to close" (artifact / evaluation / memory_ref → STABLE, same gates as esr_close), a node + relation list (nodes are domain objects the model registers via esr_node — package/service/repo/concept; relations via esr_link), a separate relation-graph tab (hand-rolled force-directed SVG, no chart library so the bundle stays pure: entities as circles, tasks as check badges, relations colored per type with direction arrows; drag nodes, pan, wheel-zoom, re-layout, hover highlights the neighborhood, clicking a node pops a floating panel with its incident relations and linked objects; dangling links are counted and warned about), an injection-preview tab that renders the exact [ENGRAM] index block (order 40) and [ESR] task/closure block (order 41) the model sees each session — same pure functions as the system-prompt sections — as two terminal-style panes with per-line coloring (block headers, task lines, drill hint, and the data-driven escalate: reminder highlighted), line/char/~token cost chips plus memory/task/link/node count chips, 20s auto-refresh and one-click copy of the raw block text (backed by the new GET /api/dsh-engram/preview?workspace=… route). Every ESR task card (board and ESR tab) carries an evidence-progress ring — a small three-arc SVG donut mapping artifact · evaluation · memory_ref, all green when closure-ready, amber while gapped, gray with no evidence yet; the board header adds an aggregate ring showing overall evidence completeness (%) plus how many in-progress tasks are closure-ready. Pure SVG, no chart library, bundle stays clean. A telemetry dashboard tab turns the /stats usage rollup (workspace × day) into a pure-SVG dashboard: three gauges for ESR proactivity (benchmarked against the 0.34 escalate threshold, amber + hint when low), recall hit rate and detail follow-through, five stat cards (total / esr / memory calls, avg hits per query, failures), a 14-day mem-vs-esr stacked bar chart and a Top-8 tool breakdown (mem blue / esr purple), 20s auto-refresh with an automatic small-sample (= promoteHits). Run esr_gcwithdry_run: true` to preview. Nothing is hard-deleted — the report ends with re-fetch pointers for everything it archived, so archives are recoverable, not lost.

Auto-capture policy

Capture is deterministic and offline — it only sees tool results, never the conversation. Exactly what earns a memory record:

Tool resultActionSignal
git commit … -m "subject"record — the written subject is the memory0.55
git merge / rebase / cherry-pick / tag / checkout -brecord (milestone)0.5
git push / git stash / commit without