fan56/dsh-topics-memory ↗★ 6

@aiwayds/dsh-topics-memory

dsh-plugin: quality-first topic memory for dsh — a topic keeps the starting question, conclusion, impact and dependencies, not the process; local-first git-traced OKF bundle, budgeted LLM-free injection 适合需要跨会话沉淀核心结论、规避冗余过程,并在后续对话中自动关联背景的用户。

パッケージ
@aiwayds/dsh-topics-memory
互換性
未検証
Harness ピア範囲
>=0.2.0-rc.2
Cordis ピア範囲
^4.0.2
バージョン
0.25.0
最終更新
2026/10/19

インストール

$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:

KeyDefaultMeaning
repoempty (local-only)GitHub sync repo owner/name; suggested dsh-topics-data; empty = back to local-only
autoInjecttruePer-turn injection master switch
injectDeduptrueSession-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
suppressEchotrueDistill-echo suppression: topics distilled from the CURRENT session's own turns are not injected back into it (provenance rides the observations log sessionId → distilledInto)
topK4Max topics injected per turn
perTopicBudget300Per-topic digest token budget
totalBudget1500Total injection budget per turn
matchThreshold0.3Hit threshold; tune from /topics stats near-miss evidence
tagBoost0.15Additive boost per tag hit (total cap across hits equals this value)
injectModepointerInjection 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)
qualityLanesampledSlow quality lane: off / sampled (1/3 of turns) / always; produced at turn/end, consumed by the next injection (consume-once), never for subagent sessions
graphDepth2depends graph walk depth (0 disables)
recencyWindowDays7Recency bonus window (+0.2)
autoObservetrueCapture atomic observations every turn
includeSubagentsfalseWhether injection and observation also engage subagent sessions (ADR 0011; off by default since 0.7.0); off skips them entirely
observationMaxChars2000Per-side per-turn observation truncation
distillProvider / distillModelempty (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
distillEveryTurns5Distill every N turns of a long session
distillOnSessionEndtrueDistill once when a session ends
distillBatchSize40Observations 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
distillMaxModelCalls8Max 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
consolidateCadencedailyConsolidation-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
deprecatedTtlDays15Deprecated 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
usageBoost0.15Usage 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
zeroOpenDecayfalseZero-open decay: halve the retrieval score of zero-open high-frequency slugs before the threshold cut (see the section below)
pushDebounceSeconds45GitHub-mode debounced push interval
jevEnabledfalseSystem One decision layer master switch (experimental): false = zero behavior change — see the Jev decision layer section above
jevBackendzenDecision endpoint: zen (free) / native / openrouter
jevModelempty (per backend: jev-1.13-free / jev-1.13.0 / typesafe/jev-1.13)Version-pinned decision model; upgrading is an explicit action
jevTimeoutMs3000Per-request decision timeout; single attempt, no retry
jevSecretFilenoneExternal secret list for the outbound secret gate; re-read when hot-changed
jevLayaFallbackfalseLocal laya pace-maker: fire a parallel laya call on every jev request; its answer takes over (degraded, relative-ranking only) when the primary fails
jevLayaUrlhttp://127.0.0.1:8000/v1/systemonelaya-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.