@aiwayds/dsh-topics-memory
提供高质量的主题记忆管理与免LLM开销的注入 适合需要跨会话沉淀核心结论、规避冗余过程,并在后续对话中自动关联背景的用户。
安裝
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:fan56/dsh-topics-memory說明文件
閱讀完整 README ↗Configuration
First-time setup belongs to /topics onboard; day-to-day tuning is /topics set — on dsh 0.1.7+ it writes the settings-page dsh-topics-memory entry (the profile patch) and every key is volatile: edits take effect immediately, no restart. Upgrading from a pre-0.1.7 install: a legacy top-level topics: section in the old settings.yaml is imported once into the new entry automatically at the next plugin boot (the audit record lands in ~/.dsh/storages/dsh-topics-memory/legacy-import.json). All keys and defaults:
| Key | Default | Meaning |
|---|---|---|
repo | empty (local-only) | GitHub sync repo owner/name; suggested dsh-topics-data; empty = back to local-only |
autoInject | true | Per-turn injection master switch |
injectDedup | true | Session-level injection dedup: topics already injected in this session are not re-injected (registry cleared at session end; budget-dropped topics stay injectable; deduped topK slots are NOT backfilled) — ADR 0012 |
suppressEcho | true | Distill-echo suppression: topics distilled from the CURRENT session's own turns are not injected back into it (provenance rides the observations log sessionId → distilledInto) |
topK | 4 | Max topics injected per turn |
perTopicBudget | 300 | Per-topic digest token budget |
totalBudget | 1500 | Total injection budget per turn |
matchThreshold | 0.3 | Hit threshold; tune from /topics stats near-miss evidence |
tagBoost | 0.15 | Additive boost per tag hit (total cap across hits equals this value) |
injectMode | pointer | Injection shape: pointer (light pointers, ≤80 tok each, topic_open pulls the full text; total budget capped at 600) / digest (full digest rendering, per-topic 300 / total 1500) |
qualityLane | sampled | Slow quality lane: off / sampled (1/3 of turns) / always; produced at turn/end, consumed by the next injection (consume-once), never for subagent sessions |
graphDepth | 2 | depends graph walk depth (0 disables) |
recencyWindowDays | 7 | Recency bonus window (+0.2) |
autoObserve | true | Capture atomic observations every turn |
includeSubagents | false | Whether injection and observation also engage subagent sessions (ADR 0011; off by default since 0.7.0); off skips them entirely |
observationMaxChars | 2000 | Per-side per-turn observation truncation |
distillProvider / distillModel | empty (distill off) | Distill lane model route; both must be set to enable. With a UI, /topics set distill-provider / distill-model without a value opens a picker panel (provider list → that provider's model catalog); a mixed provider model / provider/model value for distill-model splits into both keys |
distillEveryTurns | 5 | Distill every N turns of a long session |
distillOnSessionEnd | true | Distill once when a session ends |
distillBatchSize | 40 | Observations per distill model call. On an output-limit (max-tokens) failure the batch halves automatically (floor 5) and retries — a failing batch can no longer livelock the backlog; the shrink persists until reload or a config change. Note: /topics set distillBatchSize back to the same value does not reset the shrink — set a different value or reload the plugin |
distillMaxModelCalls | 8 | Max model calls per distill run, including the one corrective retry for ops echoing no valid observed_ids (the run stalls when the budget can't fit it). Batches already distilled keep their marks when the budget stops the run (partial progress), recorded as partial: … in the distill state |
consolidateCadence | daily | Consolidation-lane cadence: daily/3d/7d/off. At session start the plugin checks the last consolidation time (meta/consolidate-state.json) and, when due, runs the LLM gardener in the background (reusing the distill model route): local lexical clustering only feeds near-look-alike candidate clusters; four op kinds merge/promote/deprecate/refresh, out-of-scope ops are dropped; a failed call never advances the stamp, so the next start retries |
deprecatedTtlDays | 15 | Deprecated topics older than N days are dropped at session start (local rule, no model; each drop is its own git commit — history stays recoverable); 0 disables the sweep |
usageBoost | 0.15 | Usage boost (ADR 0015): topics injected/opened in the last 30 days score higher at retrieval (gate-scoped, capped at 0.2, never granted to zero-lexical candidates, structural gate not waived); 0 disables |
zeroOpenDecay | false | Zero-open decay: halve the retrieval score of zero-open high-frequency slugs before the threshold cut (see the section below) |
pushDebounceSeconds | 45 | GitHub-mode debounced push interval |
jevEnabled | false | System One decision layer master switch (experimental): false = zero behavior change — see the Jev decision layer section above |
jevBackend | zen | Decision endpoint: zen (free) / native / openrouter |
jevModel | empty (per backend: jev-1.13-free / jev-1.13.0 / typesafe/jev-1.13) | Version-pinned decision model; upgrading is an explicit action |
jevTimeoutMs | 3000 | Per-request decision timeout; single attempt, no retry |
jevSecretFile | none | External secret list for the outbound secret gate; re-read when hot-changed |
jevLayaFallback | false | Local laya pace-maker: fire a parallel laya call on every jev request; its answer takes over (degraded, relative-ranking only) when the primary fails |
jevLayaUrl | http://127.0.0.1:8000/v1/systemone | laya-serve endpoint for the pace-maker |
Zero-open decay (default off)
zeroOpenDecay: true halves the hit score of slugs the stats panel lists as 零打开高频 — truly rendered ≥5 injections in the rolling 30 days with zero topic_open events ever. The decay applies at score finalization, before the match threshold, so a decayed candidate that drops below it lands in nearMisses carrying the zero-open-decay reason — the injection log shows why it stopped ranking. Motivation: 24 high-frequency topics held the injection leaderboard with zero opens while score and opens proved only weakly correlated (the 0.3 threshold stays untouched). Default false means zero behavior change; unreadable injection/open logs skip the decay (fail-open). Toggle live with /topics set zero-open-decay on|off.