dsh-prime-memory 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.en.md +28 -0
  2. package/CHANGELOG.ja.md +30 -0
  3. package/CHANGELOG.ko.md +30 -0
  4. package/CHANGELOG.md +1220 -0
  5. package/ENGINEERING-NOTES.md +452 -0
  6. package/INSTALL.en.md +92 -0
  7. package/INSTALL.ja.md +92 -0
  8. package/INSTALL.ko.md +92 -0
  9. package/INSTALL.md +92 -0
  10. package/LICENSE +21 -0
  11. package/README.en.md +458 -0
  12. package/README.ja.md +306 -0
  13. package/README.ko.md +306 -0
  14. package/README.md +425 -0
  15. package/assets/changelog/0.8.10/01-write-only-pill.png +0 -0
  16. package/assets/changelog/0.8.9/01-panel.png +0 -0
  17. package/assets/changelog/0.8.9/02-halo.png +0 -0
  18. package/assets/changelog/0.8.9/03-layer-segmented-panel.png +0 -0
  19. package/assets/changelog/0.8.9/04-layer-l1-panel.png +0 -0
  20. package/assets/img/EmbeddingSource.png +0 -0
  21. package/assets/img/Hero.png +0 -0
  22. package/assets/img/Layers.png +0 -0
  23. package/assets/img/MemoryTools.png +0 -0
  24. package/assets/img/Modes.png +0 -0
  25. package/assets/img/ToolTrajectory.png +0 -0
  26. package/assets/img/ui-dark.jpg +0 -0
  27. package/assets/img/ui-light.jpg +0 -0
  28. package/assets/readme/bench-dialog.svg +70 -0
  29. package/assets/readme/bench-workflow.svg +79 -0
  30. package/assets/readme/flow.svg +189 -0
  31. package/assets/readme/storage.svg +115 -0
  32. package/cordis.patch.yml +16 -0
  33. package/dist/bench-control.d.ts +34 -0
  34. package/dist/bench-control.js +16 -0
  35. package/dist/client.js +4293 -0
  36. package/dist/config.d.ts +683 -0
  37. package/dist/config.js +129 -0
  38. package/dist/contract.d.ts +820 -0
  39. package/dist/contract.js +1 -0
  40. package/dist/embedding-worker.cjs +176 -0
  41. package/dist/graph/apply.d.ts +37 -0
  42. package/dist/graph/apply.js +270 -0
  43. package/dist/graph/constraints.d.ts +47 -0
  44. package/dist/graph/constraints.js +38 -0
  45. package/dist/graph/search.d.ts +16 -0
  46. package/dist/graph/search.js +115 -0
  47. package/dist/graph/types.d.ts +142 -0
  48. package/dist/graph/types.js +14 -0
  49. package/dist/hooks/capture.d.ts +32 -0
  50. package/dist/hooks/capture.js +194 -0
  51. package/dist/hooks/recall.d.ts +63 -0
  52. package/dist/hooks/recall.js +429 -0
  53. package/dist/index.d.ts +534 -0
  54. package/dist/index.js +344 -0
  55. package/dist/llm-usage.d.ts +26 -0
  56. package/dist/llm-usage.js +37 -0
  57. package/dist/llm.d.ts +153 -0
  58. package/dist/llm.js +530 -0
  59. package/dist/pipeline/graph.d.ts +35 -0
  60. package/dist/pipeline/graph.js +104 -0
  61. package/dist/pipeline/l1.d.ts +19 -0
  62. package/dist/pipeline/l1.js +271 -0
  63. package/dist/pipeline/l2.d.ts +13 -0
  64. package/dist/pipeline/l2.js +83 -0
  65. package/dist/pipeline/l3.d.ts +15 -0
  66. package/dist/pipeline/l3.js +78 -0
  67. package/dist/pipeline/rebuild.d.ts +61 -0
  68. package/dist/pipeline/rebuild.js +307 -0
  69. package/dist/pipeline/ruminate.d.ts +89 -0
  70. package/dist/pipeline/ruminate.js +298 -0
  71. package/dist/pipeline/runner.d.ts +167 -0
  72. package/dist/pipeline/runner.js +638 -0
  73. package/dist/pipeline/trigger.d.ts +40 -0
  74. package/dist/pipeline/trigger.js +75 -0
  75. package/dist/prompts/graph-projection.d.ts +70 -0
  76. package/dist/prompts/graph-projection.js +167 -0
  77. package/dist/prompts/l1-dedup.d.ts +22 -0
  78. package/dist/prompts/l1-dedup.js +251 -0
  79. package/dist/prompts/l1-extraction.d.ts +22 -0
  80. package/dist/prompts/l1-extraction.js +457 -0
  81. package/dist/prompts/persona.d.ts +23 -0
  82. package/dist/prompts/persona.js +240 -0
  83. package/dist/prompts/scene.d.ts +32 -0
  84. package/dist/prompts/scene.js +414 -0
  85. package/dist/runtime-package-lock.json +982 -0
  86. package/dist/settings.d.ts +50 -0
  87. package/dist/settings.js +355 -0
  88. package/dist/stats.d.ts +109 -0
  89. package/dist/stats.js +929 -0
  90. package/dist/store/bm25.d.ts +19 -0
  91. package/dist/store/bm25.js +63 -0
  92. package/dist/store/cost-ledger.d.ts +75 -0
  93. package/dist/store/cost-ledger.js +171 -0
  94. package/dist/store/download-queue.d.ts +79 -0
  95. package/dist/store/download-queue.js +424 -0
  96. package/dist/store/embedding-source.d.ts +118 -0
  97. package/dist/store/embedding-source.js +443 -0
  98. package/dist/store/embedding.d.ts +90 -0
  99. package/dist/store/embedding.js +206 -0
  100. package/dist/store/graph-store.d.ts +94 -0
  101. package/dist/store/graph-store.js +641 -0
  102. package/dist/store/l0.d.ts +40 -0
  103. package/dist/store/l0.js +197 -0
  104. package/dist/store/l1.d.ts +93 -0
  105. package/dist/store/l1.js +297 -0
  106. package/dist/store/local-embedding.d.ts +89 -0
  107. package/dist/store/local-embedding.js +227 -0
  108. package/dist/store/model-catalog.d.ts +48 -0
  109. package/dist/store/model-catalog.js +81 -0
  110. package/dist/store/occupancy.d.ts +30 -0
  111. package/dist/store/occupancy.js +134 -0
  112. package/dist/store/pending.d.ts +36 -0
  113. package/dist/store/pending.js +103 -0
  114. package/dist/store/persona.d.ts +15 -0
  115. package/dist/store/persona.js +60 -0
  116. package/dist/store/recall-dedupe.d.ts +26 -0
  117. package/dist/store/recall-dedupe.js +138 -0
  118. package/dist/store/runtime-installer.d.ts +59 -0
  119. package/dist/store/runtime-installer.js +243 -0
  120. package/dist/store/scenes.d.ts +24 -0
  121. package/dist/store/scenes.js +160 -0
  122. package/dist/store/search-utils.d.ts +38 -0
  123. package/dist/store/search-utils.js +100 -0
  124. package/dist/store/session-modes.d.ts +35 -0
  125. package/dist/store/session-modes.js +144 -0
  126. package/dist/store/sqlite.d.ts +246 -0
  127. package/dist/store/sqlite.js +1491 -0
  128. package/dist/store/state.d.ts +41 -0
  129. package/dist/store/state.js +72 -0
  130. package/dist/token-cost.d.ts +23 -0
  131. package/dist/token-cost.js +185 -0
  132. package/dist/tools/index.d.ts +34 -0
  133. package/dist/tools/index.js +758 -0
  134. package/dist/types.d.ts +139 -0
  135. package/dist/types.js +38 -0
  136. package/dist/util/context-occupancy.d.ts +68 -0
  137. package/dist/util/context-occupancy.js +92 -0
  138. package/dist/util/filelog.d.ts +6 -0
  139. package/dist/util/filelog.js +108 -0
  140. package/dist/util/io.d.ts +18 -0
  141. package/dist/util/io.js +97 -0
  142. package/dist/util/recall-budget.d.ts +31 -0
  143. package/dist/util/recall-budget.js +84 -0
  144. package/dist/util/sanitize.d.ts +11 -0
  145. package/dist/util/sanitize.js +67 -0
  146. package/dist/util/text.d.ts +16 -0
  147. package/dist/util/text.js +61 -0
  148. package/dist/util/tokenizer.d.ts +9 -0
  149. package/dist/util/tokenizer.js +50 -0
  150. package/dsh.plugin.json +22 -0
  151. package/package.json +118 -0
package/README.ja.md ADDED
@@ -0,0 +1,306 @@
1
+ <div align="center">
2
+
3
+ <img src="./assets/img/Hero.png" width="100%"
4
+ alt="DeepSeek Harness ヒーロー画像:会話がバックグラウンドで階層的に蒸留されて記憶に、モデルの各ステップ前に自動で想起・注入される">
5
+
6
+ # dsh-prime-memory
7
+
8
+ **DeepSeek Harness 向けの階層的蒸留記憶プラグイン:会話はバックグラウンドで L0 捕捉 → L1 原子記憶 → L2 シナリオ統合 → L3 ペルソナ蒸留を経て処理され、関連記憶はモデルの各ステップ前に自動でコンテキストへ注入されます。**
9
+
10
+ [中文 README](./README.md) · [English README](./README.en.md) · [日本語 README](./README.ja.md) · [한국어 README](./README.ko.md) · [最新リリース](https://github.com/drscrewdriver/dsh-prime-memory/releases/latest) · [問題を報告](https://github.com/drscrewdriver/dsh-prime-memory/issues)
11
+
12
+ [![npm version](https://img.shields.io/npm/v/dsh-prime-memory?color=6f83ff&style=flat-square&label=npm)](https://www.npmjs.com/package/dsh-prime-memory)
13
+ [![DSH 0.1.1-rc.2](https://img.shields.io/badge/DSH-0.1.1--rc.2-8b5cf6?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
14
+ [![MIT License](https://img.shields.io/badge/license-MIT-536990?style=flat-square)](LICENSE)
15
+
16
+ </div>
17
+
18
+ <details open>
19
+ <summary>🌐 言語 / Language</summary>
20
+
21
+ - [中文 README](./README.md)
22
+ - [English README](./README.en.md)
23
+ - [日本語 README](./README.ja.md)
24
+ - [한국어 README](./README.ko.md)
25
+ - [インストールガイド(日本語)](./INSTALL.ja.md)
26
+ - [Installation guide (English)](./INSTALL.en.md)
27
+ - [中文安装指南](./INSTALL.md)
28
+ - [한국어 설치 안내](./INSTALL.ko.md)
29
+ - [日本語 changelog](./CHANGELOG.ja.md)
30
+ - [Changelog (English)](./CHANGELOG.en.md)
31
+ - [更新日志(中文)](./CHANGELOG.md)
32
+ - [한국어 changelog](./CHANGELOG.ko.md)
33
+
34
+ </details>
35
+
36
+ > **互換性の注意**:本プラグインはドキュメントを日本語・韓国語で提供しますが、公式 DSH の `LocaleRuntime` が登録する言語は `zh` / `en` のみです。`ja` / `ko` を選択すると `locale "<id>" is not registered` となります。プラグイン側は辞書を持ち込めますが、DSH グローバルのロケール一覧は拡張できません。DSH を fork して `LOCALE_IDS`(locale-settings.ts)と `LOCALES` ラベル(client/index.ts)を更新し再ビルドすることで利用可能になります。
37
+
38
+ ## DSH バージョン互換マトリクス
39
+
40
+ | DSH バージョン | settings 登録 API | 状態 |
41
+ |---|---|---|
42
+ | 0.1.1-rc.2 | `settings.register()`(ライブスコープ) | ✅ 検証済み |
43
+ | 0.1.2-rc.1 | `settings.register()`(フォールバック可) | ⚠️ フレームワークドキュメントから推定、未実測 |
44
+ | 0.1.3-rc.1 | `settings.register()`(フォールバック可) | ⚠️ 未実測(0.1.3+ で名前空間が文字列化、本プラグインは対応済み) |
45
+ | 0.1.5-rc.2 | `settings.register()`(フォールバック可) | ⚠️ 未実測。Session V3 の surface セマンティクスと入力バー/設定スロットは回帰待ち |
46
+
47
+ > 互換メカニズム:settings 登録は 3 分岐のランタイム判定(`register` → `installSection` ブリッジ → 常時オン縮退)。
48
+ > 詳細は [CHANGELOG.md](./CHANGELOG.md) の 0.11.0 エントリ参照。`dsh.plugin.json` は
49
+ > `engines.dsh: ">=0.1.1-rc.2 <0.2.0-0"` を宣言。
50
+
51
+ ## クイックスタート
52
+
53
+ Node ≥ 22.16 が必要です。2 通りの呼び出し方式から選べます(`npx` 接頭辞は以下のどの `dsh` コマンドも置き換え可能):
54
+
55
+ ```bash
56
+ # 方法1:npx で公式 CLI を直接実行(dsh の事前導入不要。バージョン固定も可、例: dsh-prime-memory@0.8.4)
57
+ npx -y @deepseek-ai/dsh plugin --profile web add dsh-prime-memory
58
+
59
+ # 方法2:dsh CLI 導入済みの場合(dsh は pnpm フォワーダ。未導入なら先に npm i -g pnpm)
60
+ dsh plugin --profile web add dsh-prime-memory
61
+
62
+ # その他のソース:GitHub リポジトリ / ローカルパス(開発・デバッグ用。link: はリポジトリを指し、npm run build + dsh 再起動で反映)
63
+ dsh plugin --profile web add https://github.com/drscrewdriver/dsh-prime-memory
64
+ dsh plugin --profile web add /path/to/dsh-prime-memory
65
+ ```
66
+
67
+ ### Agent にインストールさせる(推奨)
68
+
69
+ 現在の Agent がターミナルコマンドを実行できるなら、以下の文をそのまま送ってください:
70
+
71
+ ```text
72
+ DeepSeek Harness の web プロファイルに dsh-prime-memory プラグインをインストールしてください。
73
+
74
+ 以下の2コマンドのみを実行し、他のプロファイルは変更しないでください:
75
+ dsh plugin --profile web add dsh-prime-memory
76
+ dsh --profile web --dump-config
77
+
78
+ 出力に dsh-prime-memory が表示されたら、インストール結果を教えてください。
79
+ 稼働中の DSH を勝手に閉じたり再起動したりしないでください。インストール後、DSH Web Host の手動再起動を促してください。
80
+ ```
81
+
82
+ Agent はインストール結果と、設定に `dsh-prime-memory` が現れたかを報告します。
83
+
84
+ 本パッケージは `dsh.bundle` 合成層(`cordis.patch.yml`)を宣言しており、インストール後に**プラグイン行が自動マウント**されます——`$DSH_HOME/profiles/web/cordis.patch.yml` を手修正する必要はありません。その後 DeepSeek Harness を再起動し、確認:`~/.dsh/memory/` 配下に `conversations/ records/ scenes/` ディレクトリと `memory.db` が現れればプラグイン適用成功;設定画面に「記憶」ページ、入力バーにモードピルが現れればクライアント側準備完了です。
85
+
86
+ **アンインストール**:`dsh plugin --profile web remove dsh-prime-memory` + 再起動。データは `~/.dsh/memory/` に残ります。不要ならそのディレクトリごと手動削除してください。
87
+
88
+ ### ソースから開発
89
+
90
+ ```bash
91
+ git clone https://github.com/drscrewdriver/dsh-prime-memory
92
+ cd dsh-prime-memory
93
+ npm install && npm run build
94
+ dsh plugin --profile web add . # link: インストール。コード変更後は npm run build + dsh 再起動で反映
95
+ npm run smoke # スモークテスト(先に再ビルド:下記コマンド参照)
96
+ npx tsc src/smoke.ts --outDir dist-smoke --module nodenext --moduleResolution nodenext --target es2022 --strict --skipLibCheck --esModuleInterop
97
+ ```
98
+
99
+ ## ランタイム・データフロー
100
+
101
+ <p align="center">
102
+ <img src="./assets/readme/flow.svg" width="100%"
103
+ alt="dsh-prime-memory のランタイム・データフロー:左のユーザーとアシスタントのセッションイベントがプラグイン(L0 捕捉、L1–L3 蒸留、検索想起、記憶ツール)に流れ込み、プラグインが関連記憶を agent/pre-step で右の DSH コアへ注入。蒸留はコアの ctx.llm を再利用、データは ~/.dsh/memory/ に二重書き込み">
104
+ </p>
105
+
106
+ プラグインは DSH ネイティブのイベントシームに付着します(`session/event` で捕捉、`agent/pre-step` で注入)、蒸留はホストの `ctx.llm` を再利用します。想起は**メッセージ側注入**として提示されます——関連記憶はユーザーの新メッセージの直前に置かれた合成メッセージとして表示され、チャットフローには **「コンテキスト注入 · memory」** 行(展開でヒット内容を表示)として現れます。注入内容は長さ・時間予算で上限があり、超過は切り捨て/タイムアウトでスキップされ、対話を遅延させることはありません。**同一セッション重複排除**:すでに注入済みの記憶は再注入しません(コンテキストにあればトークン節約)。`/compact` 等でリセットされれば再注入可能。**時効重み付け**:想起順位は `関連度 × max(0.5, 0.5^(最終更新からの日数/30))` でソフト重み付けされます(`recall.decayHalfLifeDays` で調整、`0`=無効)。
107
+
108
+ **コストダッシュボード**:各蒸留 LLM 呼び出し(抽出/重複排除/L2/L3)のトークンコストを `provider/model` 単位で SQLite 明細表へ記録(保持期間は設定可、既定 365 日)。設定 → 記憶 → **コスト** タブで可視化。
109
+
110
+ **記憶ツール(3)**:
111
+
112
+ - memory_search
113
+ - conversation_search
114
+ - memory_read_scene
115
+
116
+ ## 階層的記憶(L0–L3)
117
+
118
+ <p align="center">
119
+ <img src="./assets/img/Layers.png" width="100%"
120
+ alt="階層的記憶の4層:L0 生会話 → L1 原子記憶 → L2 シナリオブロック → L3 コアペルソナ">
121
+ </p>
122
+
123
+ ## セッション単位の記憶モード
124
+
125
+ <p align="center">
126
+ <img src="./assets/img/Modes.png" width="100%"
127
+ alt="セッション単位の記憶モード:4つの停点(日常・工作・智能・关闭)を持つガラスカプセル型レール">
128
+ </p>
129
+
130
+ - **コントロール**:入力バー内、モードセレクタ右のピル(`記憶·自動`)をクリックで档位スライダが開く(深浅テーマ自適応)。
131
+ - ポップオーバー下半は**セッション情報エリア**:想起ヒット、バッチ進行、本セッション産出記憶数、セッションメッセージ数に加え、異常状態行(ストレージ低下 / ベクトル検索不可)と全体サマリ。
132
+ - 各セッションの選択は sessionId 単位で `session-modes.json` に永続化され、再起動/復元でも失われません。
133
+ - **読み書き分離(#38)**:ポップオーバー内の「注入」3態スイッチ(全体に従う / オン / オフ)——「オフ」で**書き込み専用セッション**:捕捉と蒸留は通常通り(会話は L0→L1→L2/L3 へ蓄積)ですが、本セッションへは何も注入されません。ピル面文は `記憶·只写` に変化。
134
+
135
+ ## UI プレビュー
136
+
137
+ <p align="center">
138
+ <img src="./assets/img/ui-dark.jpg" width="49.5%"
139
+ alt="ダークテーマの設定ページ記憶ブラウザ概要">
140
+ <img src="./assets/img/ui-light.jpg" width="49.5%"
141
+ alt="ライトテーマの同一設定ページ">
142
+ </p>
143
+
144
+ ## 測定比較(DSH-MemBench:自動ベンチマーク)
145
+
146
+ 「見た目」に加えて、この節は**自動ベンチマーク**の実測数値で「**有効にすると何が得られるか**」に答えます([`bench/`](./bench/)、1コマンドで再現可能)。手法:同一シナリオバンク・同一入力で **A 群(記憶オン)を3回マージ**、**B 群(記憶オフ)を1回**(記憶なしの長タスクは数倍のトークンを消費するためコストガードレール)。対話トラックは A 群のみ。
147
+
148
+ ### 対話トラック(20 シナリオ × 10 型 × 3 回 = 420 問)
149
+
150
+ > 0.8.5 ベースライン(A 群データ;対話トラック B 群は廃止、A 群のみ)。
151
+
152
+ <p align="center">
153
+ <img src="./assets/readme/bench-dialog.svg" width="100%"
154
+ alt="DSH-MemBench 対話トラック精度図(A群・記憶オン):総精度 95.2%(400/420)">
155
+ </p>
156
+
157
+ **想起の二重チャネル**(A 群):受動注入の想起率 **78.1%**(281/360)、残りはモデルが**記憶ツールを能動呼び出し**で補完(106 問が能動クエリ、うち 75 問をツールで救済)。エンドツーエンド 95.2% は両チャネルとモデルの活用の合成結果。記憶庫が膨張しても精度は前段 92.8% → 後段 97.7% へ上昇、検索層 recall@5 は合成ノイズ 600 件注入でも 2.8pp しか低下しませんでした。
158
+
159
+ **階層別の弱点**:検索層オフライン指標(recall@5)は全体 73.3%(イベント順序 0%、シナリオ想起 50%)。**効率の三角形**(記憶のコスト):注入は遅延を増やさず(注入ターンは平均 210ms 速い)、注入は各ターン入力の約 10.3%、蒸留全リンクは捕捉メッセージ1件あたり約 2727 入力 / 240 出力トークン(1172 回呼び出し・0 失敗)。
160
+
161
+ ### ワークフロートラック(0.8.3 保存版)
162
+
163
+ <p align="center">
164
+ <img src="./assets/readme/bench-workflow.svg" width="100%"
165
+ alt="DSH-MemBench ワークフロートラック A/B 対照図">
166
+ </p>
167
+
168
+ **プローブ段完了 85.5% vs 43.5%(+42pp)**:3 つの新プローブ原型(フロー知識更新 / 双子ランブック識別 / スタイル規約継続)で A 群は全て 12/12 満点かつ3回一致。B 群はスタイル規約プローブで **0/4**(命名/構造/桁区切り/フッター規約は記憶のみに存在)。
169
+
170
+ **長タスクコスト:B 群のセッションあたり入力トークンは A 群の 6.8 倍**(1.81M vs 266k)。
171
+
172
+ ### 手法と再現
173
+
174
+ ```bash
175
+ node bench/harness/run.mjs --arm A --repeats 3 --provider deepseek-official --model deepseek-v4-flash # 対話トラック(A 群のみ)
176
+ node bench/harness/run.mjs --track workflow --arm AB --repeats 3 ... # ワークフロートラック(A/B 並列)
177
+ node bench/harness/run.mjs --track lifecycle --arm A ... # ライフサイクルトラック
178
+ node bench/harness/report.mjs --latest [dialog|workflow] # 集計レポート
179
+ node bench/harness/retrieval-metrics.mjs <runDir> --flood 200,600 # 検索層指標 + 注入曲線
180
+ ```
181
+
182
+ 詳細は [`bench/baseline/`](./bench/baseline/) を参照。
183
+
184
+ ## ストレージ・レイアウト
185
+
186
+ <p align="center">
187
+ <img src="./assets/readme/storage.svg" width="100%"
188
+ alt="ストレージ・レイアウト:二重書き込みアーキテクチャ(JSONL 真実源 + memory.db 検索庫)">
189
+ </p>
190
+
191
+ ベクトル能力は既定でオフ(純 FTS)。DSH の `ctx.llm` には embeddings エンドポイントがなく、意味検索は**3態の埋め込みソース**(オフ / リモート / ローカル)が提供します。設定画面からランタイムで切り替え可能(次節参照)。
192
+
193
+ ## 意味検索(埋め込みソース)
194
+
195
+ 設定 → 記憶 → 概要 → 意味検索で埋め込みソースを選択、即時反映、設定変更・再起動不要:
196
+
197
+ <p align="center">
198
+ <img src="./assets/img/EmbeddingSource.png" width="70%"
199
+ alt="設定画面の意味検索(埋め込みソース)パネル:3態セレクタ(オフ/ローカル/リモート)">
200
+ </p>
201
+
202
+ 3 つのソース:**オフ**(既定、純 BM25 キーワード検索)、**リモート**(任意の OpenAI 互換 `/embeddings` サービスを持ち込み、`embedding.*` 4 点セットが揃えば選択可)、**ローカル**(内蔵モデルカタログから選択、ONNX 量子化 **CPU 推論**——API Key 不要、データは本機から出ない)。ローカルカタログはプラグイン内蔵の許可リスト(各モデルを revision + ファイルごと sha256 で固定、任意リポジトリはダウンロード不可)。
203
+
204
+ - **ダウンロード**:モデルカード1クリック(既定ミラー `hf-mirror.com`、再開対応 + sha256 整合性検証)。単ファイル失敗は自動リトライ(キャッシュキー変更 `?dshmem-retry=N`)。
205
+ - **オンデマンド・ランタイム**:ローカル档への初回切り替え時のみ推論ランタイム(transformers.js、約 100〜200MB)をデータディレクトリ `runtime/` へ導入(プラグイン依存ツリー・導入ディレクトリには触らない)。モデル読み込みと推論は**専用ワーカースレッド**で実行。
206
+ - **ライブ切り替え**:1クリックでソース交換——バックグラウンドで全量再埋め込み(進行可視・キャンセル可、その間は検索がキーワードへ自動劣化、対話に影響なし)。
207
+ - **有効規則 = デプロイ上限 AND ランタイム選択**:`embedding.allowLocalModels=false` でローカル档を全体無効化、未設定ならリモート档は選択不可(企業デプロイで収口可)。状態は `embedding-source.json` に永続化。
208
+
209
+ ## 設定
210
+
211
+ 上書き設定は profile 自身の `cordis.patch.yml` に**トップレベルの裸 patch エントリ**で書きます(直接 `id:` を使い、`insert:` で包まないこと):
212
+
213
+ ```yaml
214
+ - id: dsh-memory
215
+ name: dsh-prime-memory
216
+ config: # キーは行単位で全体置換(ディープマージなし)
217
+ family: auto # 新セッションの既定档:auto | chat | work
218
+ llm:
219
+ provider: ''
220
+ model: ''
221
+ ```
222
+
223
+ | フィールド | 既定 | 説明 |
224
+ | --- | --- | --- |
225
+ | `family` | `auto` | 新セッションの既定記憶档:`auto` \| `chat` \| `work` |
226
+ | `dataDir` | `$DSH_HOME/memory` | データディレクトリ |
227
+ | `capture.enabled` | `true` | L0 捕捉 |
228
+ | `capture.stripCodeBlocks` | `true` | アシスタントメッセージからコードブロックを除去 |
229
+ | `capture.maxMessageChars` | `4000` | 単メッセージ最大文字数 |
230
+ | `extract.enabled` | `true` | L1 抽出 |
231
+ | `extract.minMessages` | `6` | 定常トリガ閾値:単セッションが N 件新メッセージを溜めて L1 抽出を1回実行。立ち上がりは 1→2→4→…→N と倍増 |
232
+ | `extract.idleSeconds` | `300` | アイドル兜底:セッションが N 秒無言で未蒸留スライスを落とす。`0` で無効 |
233
+ | `extract.backgroundMessages` | `10` | 抽出時付随の背景メッセージ数 |
234
+ | `extract.candidatePool` | `5` | 重複排除候補プールサイズ |
235
+ | `l2.enabled` | `true` | L2 シナリオ統合 |
236
+ | `l2.minNewMemories` | `5` | 前回 L2 からの新記憶閾値 |
237
+ | `l2.maxScenes` | `12` | シナリオブロック数上限 |
238
+ | `l2.sceneContextLimit` | `3` | L2 prompt 付随の類似シナリオ全文上限 |
239
+ | `l3.enabled` | `true` | L3 ペルソナ蒸留 |
240
+ | `l3.interval` | `20` | L3 蒸留間隔(新記憶件数) |
241
+ | `recall.enabled` | `true` | 自動想起 |
242
+ | `recall.maxResults` | `5` | 各新ユーザーメッセージ前に注入する L1 件数上限 |
243
+ | `recall.maxCharsPerMemory` | `500` | 注入記憶1件の文字上限(超過は切り捨て)。`0` で無制限 |
244
+ | `recall.maxTotalRecallChars` | `2000` | 1回注入の総文字上限。`0` で無制限 |
245
+ | `recall.timeoutMs` | `5000` | 想起総予算(ms)。タイムアウトはそのターンの注入をスキップ。`0` で無制限 |
246
+ | `recall.includePersona` | `true` | システムプロンプトへペルソナ文脈注入(`<user-persona>`、安定域) |
247
+ | `recall.includeSceneNav` | `true` | システムプロンプトへシナリオナビ注入(`<scene-navigation>`、安定域) |
248
+ | `recall.strategy` | `hybrid` | 検索戦略:`keyword` / `embedding` / `hybrid` |
249
+ | `recall.scoreThreshold` | `0.3` | 想起スコア閾値(これ未満は注入しない) |
250
+ | `recall.decayHalfLifeDays` | `30` | 想起時効減衰半減期(日、`0`=無効) |
251
+ | `embedding.enabled` | `false` | ベクトル検索スイッチ。オフは純 FTS |
252
+ | `embedding.baseUrl` | 空 | OpenAI 互換 `/embeddings` アドレス |
253
+ | `embedding.apiKey` | 空 | API Key(**リモート档は任意**——ローカル自己ホストの免キー `/embeddings` も許可) |
254
+ | `embedding.model` | 空 | 埋め込みモデル名 |
255
+ | `embedding.dimensions` | `0` | ベクトル次元(有効時必須) |
256
+ | `embedding.maxInputChars` | `5000` | 単テキスト最大文字数(超長は切り捨て) |
257
+ | `embedding.timeoutMs` | `10000` | 単回埋め込み呼び出しタイムアウト(ms) |
258
+ | `embedding.allowLocalModels` | `true` | ローカル埋め込み档を許可(デプロイ上限) |
259
+ | `embedding.mirror` | `https://hf-mirror.com` | ローカルモデルダウンロードミラー根 |
260
+ | `embedding.proxy` | `''` | モデルダウンロードプロキシ3態:`''`(既定)= プロキシ環境変数自動検出;`none` = 強制直結無効;その他 = プロキシ URL |
261
+ | `llm.provider/model` | 空 | 蒸留モデル静的ルート(デプロイ pin):両欄揃えでロック |
262
+ | `llm.fallbacks` | `[]` | 蒸留フォールバックチェーン(主ルート失敗時に順次試行) |
263
+ | `llm.layerRoutes` | `{}` | **層別蒸留ルーティング**:`l1`/`l2`/`l3` 各に完全チェーン |
264
+ | `llm.maxTokens` | `65536` | 非層別呼び出しの兜底出力総闸 |
265
+ | `llm.reasoningEffort` | 空 | 蒸留思考档位:空 = **自動** |
266
+ | `llm.temperature` | `0.3` | 蒸留温度 |
267
+ | `llm.maxInputChars` | `700000` | 単回蒸留入力文字予算 |
268
+ | `llm.timeoutMs` | `120000` | 単回蒸留呼び出しタイムアウト(ms) |
269
+ | `tokenCost.retentionDays` | `365` | 蒸留コスト明細保持日数。`0` = 永久 |
270
+ | `tools` | `true` | モデル呼び出し可能な記憶ツールを登録するか |
271
+ | `benchControl` | `false` | ベンチ制御サービス登録(既定オフ) |
272
+
273
+ ### 蒸留フォールバックチェーンと遅い TTFT モデル
274
+
275
+ 一部プロバイダの無料/遅い档位は**最初のトークン遅延(TTFT)が 20 秒超**になり得ます。3 つの緩和策:
276
+
277
+ 1. **ルート切り替え**(最も直接):設定 → 記憶 → 概要 → 蒸留パラメータのルートチェーンエディタで主ルートを即時変更。
278
+ 2. **フォールバックチェーン**(自動降格):主ルート失敗時に順次バックアップルートを試行。
279
+ 3. **層別ルーティング**:L1(高頻度・安価・安定重視)と L3(低頻度・強能力)で別チェーン。
280
+ 4. **タイムアウト引き上げ**:`llm.timeoutMs` はルートが実際に遅いがゲートウェイが切らない場合のみ有効。
281
+
282
+ ## ログとトラブルシューティング
283
+
284
+ dsh ホストはプラグインのログをコンソールへ出力します。プラグインは info 以上をデータディレクトリの `memory.log` にもミラーします。1 ターンの典型経路:`L0 捕捉` → `L0 落盘` → `蒸留パイプライン開始` → `LLM 呼び出し` → `L1 段完了` → `パイプライン終了`;次ターン冒頭は `想起注入 N 件 L1`。
285
+
286
+ ## MemoryCore との違い
287
+
288
+ - 完全なパイプラインを内蔵(外部 Gateway 非依存)、蒸留は DSH 自身の LLM を再利用;
289
+ - L2/L3 を「LLM がファイルツールを操作」から「LLM が操作 JSON / 完全文書を出力、工学的側が実行」へ変更;
290
+ - 想起注入点は `agent/pre-step`(メッセージ側合成メッセージ)+ エージェント作用域 `systemPrompt.context`(ペルソナ/ナビ安定域);
291
+ - ストレージ/検索は公式 sqlite バックエンドの単機削ぎ版(マルチテナント分離列・TCVDB クラウドバックエンド・監査表を削除;トークン化は公式同様 jieba を使用)。
292
+
293
+ ## ロードマップ
294
+
295
+ [Issues](https://github.com/drscrewdriver/dsh-prime-memory/issues) で要望と優先度を募集中:
296
+
297
+ - [ ] **Git ブランチ認識**:記憶を現在の git ブランチと関連付け、想起をブランチでフィルタ/強調
298
+ - [ ] **Claude Code / Codex 記憶インポート**:既存資産(`CLAUDE.md`、Claude Code 記憶ファイル、Codex `AGENTS.md` 等)の1クリック移行
299
+
300
+ ## 謝辞
301
+
302
+ 核心記憶能力(階層的蒸留パイプライン、プロンプト設計、二重書き込みストレージ)は [TencentCloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory) の **MemoryCore** を参考にしています。
303
+
304
+ ## License
305
+
306
+ [MIT](LICENSE)
package/README.ko.md ADDED
@@ -0,0 +1,306 @@
1
+ <div align="center">
2
+
3
+ <img src="./assets/img/Hero.png" width="100%"
4
+ alt="DeepSeek Harness 히어로 이미지: 대화가 백그라운드에서 계층적으로 증류되어 기억으로, 모델의 매 스텝 전에 자동으로 회상·주입됨">
5
+
6
+ # dsh-prime-memory
7
+
8
+ **DeepSeek Harness용 계층적 증류 기억 플러그인: 대화는 백그라운드에서 L0 포착 → L1 원자 기억 → L2 장면 통합 → L3 페르소나 증류를 거쳐 처리되며, 관련 기억은 모델의 매 스텝 전에 자동으로 컨텍스트에 주입됩니다.**
9
+
10
+ [中文 README](./README.md) · [English README](./README.en.md) · [日本語 README](./README.ja.md) · [한국어 README](./README.ko.md) · [최신 릴리스](https://github.com/drscrewdriver/dsh-prime-memory/releases/latest) · [문제 제보](https://github.com/drscrewdriver/dsh-prime-memory/issues)
11
+
12
+ [![npm version](https://img.shields.io/npm/v/dsh-prime-memory?color=6f83ff&style=flat-square&label=npm)](https://www.npmjs.com/package/dsh-prime-memory)
13
+ [![DSH 0.1.1-rc.2](https://img.shields.io/badge/DSH-0.1.1--rc.2-8b5cf6?style=flat-square)](https://github.com/deepseek-ai/deepseek-harness)
14
+ [![MIT License](https://img.shields.io/badge/license-MIT-536990?style=flat-square)](LICENSE)
15
+
16
+ </div>
17
+
18
+ <details open>
19
+ <summary>🌐 언어 / Language</summary>
20
+
21
+ - [中文 README](./README.md)
22
+ - [English README](./README.en.md)
23
+ - [日本語 README](./README.ja.md)
24
+ - [한국어 README](./README.ko.md)
25
+ - [설치 안내(한국어)](./INSTALL.ko.md)
26
+ - [Installation guide (English)](./INSTALL.en.md)
27
+ - [中文安装指南](./INSTALL.md)
28
+ - [日本語インストールガイド](./INSTALL.ja.md)
29
+ - [한국어 changelog](./CHANGELOG.ko.md)
30
+ - [Changelog (English)](./CHANGELOG.en.md)
31
+ - [更新日志(中文)](./CHANGELOG.md)
32
+ - [日本語 changelog](./CHANGELOG.ja.md)
33
+
34
+ </details>
35
+
36
+ > **호환성 참고**: 본 플러그인은 일본어·한국어 문서를 제공하지만, 공식 DSH의 `LocaleRuntime`이 등록하는 언어는 `zh` / `en`뿐입니다. `ja` / `ko`를 선택하면 `locale "<id>" is not registered` 오류가 납니다. 플러그인은 자체 사전을 들고 있을 수 있으나 DSH 전역 로케일 목록은 확장할 수 없습니다. DSH를 fork하여 `LOCALE_IDS`(locale-settings.ts)와 `LOCALES` 라벨(client/index.ts)을 갱신하고 재빌드하면 사용 가능해집니다.
37
+
38
+ ## DSH 버전 호환성 매트릭스
39
+
40
+ | DSH 버전 | settings 등록 API | 상태 |
41
+ |---|---|---|
42
+ | 0.1.1-rc.2 | `settings.register()`(라이브 스코프) | ✅ 검증됨 |
43
+ | 0.1.2-rc.1 | `settings.register()`(폴백 가능) | ⚠️ 프레임워크 문서 기반 추정, 미실측 |
44
+ | 0.1.3-rc.1 | `settings.register()`(폴백 가능) | ⚠️ 미실측(0.1.3+에서 네임스페이스가 문자열화, 본 플러그인은 대응 완료) |
45
+ | 0.1.5-rc.2 | `settings.register()`(폴백 가능) | ⚠️ 미실측. Session V3 surface 시맨틱스와 입력바/설정 슬롯 회귀 대기 |
46
+
47
+ > 호환 메커니즘: settings 등록은 3분기 런타임 분기(`register` → `installSection` 브리지 → 상시 온 강등).
48
+ > 자세한 내용은 [CHANGELOG.md](./CHANGELOG.md)의 0.11.0 항목 참조. `dsh.plugin.json`은
49
+ > `engines.dsh: ">=0.1.1-rc.2 <0.2.0-0"` 선언.
50
+
51
+ ## 빠른 시작
52
+
53
+ Node ≥ 22.16 필요. 두 가지 호출 방식 중 선택(`npx` 접두사는 아래 모든 `dsh` 명령을 대체 가능):
54
+
55
+ ```bash
56
+ # 방식 1: npx로 공식 CLI 직접 실행(dsh 사전 설치 불필요. 버전 고정 가능, 예: dsh-prime-memory@0.8.4)
57
+ npx -y @deepseek-ai/dsh plugin --profile web add dsh-prime-memory
58
+
59
+ # 방식 2: dsh CLI 설치된 경우(dsh는 pnpm 포워더. 없으면 먼저 npm i -g pnpm)
60
+ dsh plugin --profile web add dsh-prime-memory
61
+
62
+ # 기타 소스: GitHub 저장소 / 로컬 경로(개발·디버깅용. link: 는 저장소를 가리키며, npm run build + dsh 재시작으로 반영)
63
+ dsh plugin --profile web add https://github.com/drscrewdriver/dsh-prime-memory
64
+ dsh plugin --profile web add /path/to/dsh-prime-memory
65
+ ```
66
+
67
+ ### Agent에게 설치시키기(권장)
68
+
69
+ 현재 Agent가 터미널 명령을 실행할 수 있다면 아래 문장을 그대로 보내세요:
70
+
71
+ ```text
72
+ DeepSeek Harness의 web 프로파일에 dsh-prime-memory 플러그인을 설치해 주세요.
73
+
74
+ 다른 프로파일은 수정하지 말고 아래 두 명령만 실행해 주세요:
75
+ dsh plugin --profile web add dsh-prime-memory
76
+ dsh --profile web --dump-config
77
+
78
+ 출력에 dsh-prime-memory가 나타나면 설치 결과를 알려 주세요.
79
+ 실행 중인 DSH를 임의로 닫거나 재시작하지 마세요. 설치 후 DSH Web Host 수동 재시작을 알려 주세요.
80
+ ```
81
+
82
+ Agent는 설치 결과와 설정에 `dsh-prime-memory`가 나타났는지 보고합니다.
83
+
84
+ 본 패키지는 `dsh.bundle` 합성 계층(`cordis.patch.yml`)을 선언하며, 설치 후 **플러그인 행이 자동 마운트**됩니다——`$DSH_HOME/profiles/web/cordis.patch.yml`을 손으로 고칠 필요가 없습니다. 이후 DeepSeek Harness를 재시작하고 확인:`~/.dsh/memory/` 아래에 `conversations/ records/ scenes/` 디렉터리와 `memory.db`가 나타나면 플러그인 적용 성공;설정 페이지에 "기억" 페이지, 입력 바에 모드 pill이 나타나면 클라이언트 준비 완료.
85
+
86
+ **제거**:`dsh plugin --profile web remove dsh-prime-memory` + 재시작. 데이터는 `~/.dsh/memory/`에 남습니다. 필요 없으면 해당 디렉터리 전체를 수동 삭제하세요.
87
+
88
+ ### 소스에서 개발
89
+
90
+ ```bash
91
+ git clone https://github.com/drscrewdriver/dsh-prime-memory
92
+ cd dsh-prime-memory
93
+ npm install && npm run build
94
+ dsh plugin --profile web add . # link: 설치. 코드 변경 후 npm run build + dsh 재시작으로 반영
95
+ npm run smoke # 스모크 테스트(먼저 재빌드: 아래 명령 참조)
96
+ npx tsc src/smoke.ts --outDir dist-smoke --module nodenext --moduleResolution nodenext --target es2022 --strict --skipLibCheck --esModuleInterop
97
+ ```
98
+
99
+ ## 런타임 데이터 흐름
100
+
101
+ <p align="center">
102
+ <img src="./assets/readme/flow.svg" width="100%"
103
+ alt="dsh-prime-memory 런타임 데이터 흐름: 좌측 사용자·어시스턴트 세션 이벤트가 플러그인(L0 포착, L1–L3 증류, 검색 회상, 기억 도구)으로 흐르고, 플러그인이 관련 기억을 agent/pre-step에서 우측 DSH 코어로 주입. 증류는 코어의 ctx.llm 재사용, 데이터는 ~/.dsh/memory/에 이중 기록">
104
+ </p>
105
+
106
+ 플러그인은 DSH 네이티브 이벤트 심(`session/event`로 포착, `agent/pre-step`로 주입)에 부착되며, 증류는 호스트의 `ctx.llm`을 재사용합니다. 회상은 **메시지 측 주입**으로 표시됩니다——관련 기억은 사용자의 새 메시지 바로 앞에 배치된 합성 메시지로 표시되며, 채팅 흐름에는 **"컨텍스트 주입 · memory"** 행(펼치면 히트 내용 표시)으로 나타납니다. 주입 내용은 길이·시간 예산으로 제한되며, 초과는 잘림/타임아웃으로 건너뛰어 대화를 지연시키지 않습니다. **동일 세션 중복 제거**:이미 주입된 기억은 재주입하지 않습니다(`/compact` 등으로 리셋되면 재주입 가능). **신선도 가중**:회상 순위는 `관련도 × max(0.5, 0.5^(마지막 갱신 후 경과일/30))`로 소프트 가중됩니다(`recall.decayHalfLifeDays`로 조정, `0`=비활성).
107
+
108
+ **비용 대시보드**:각 증류 LLM 호출(추출/중복제거/L2/L3)의 토큰 비용을 `provider/model` 단위로 SQLite 명세 테이블에 기록(보존 기간 설정 가능, 기본 365일). 설정 → 기억 → **비용** 탭에서 시각화.
109
+
110
+ **기억 도구(3)**:
111
+
112
+ - memory_search
113
+ - conversation_search
114
+ - memory_read_scene
115
+
116
+ ## 계층적 기억(L0–L3)
117
+
118
+ <p align="center">
119
+ <img src="./assets/img/Layers.png" width="100%"
120
+ alt="계층적 기억의 4계층: L0 원시 대화 → L1 원자 기억 → L2 장면 블록 → L3 코어 페르소나">
121
+ </p>
122
+
123
+ ## 세션 단위 기억 모드
124
+
125
+ <p align="center">
126
+ <img src="./assets/img/Modes.png" width="100%"
127
+ alt="세션 단위 기억 모드: 4개 정지점(日常·工作·智能·关闭)을 가진 유리 캡슐 레일">
128
+ </p>
129
+
130
+ - **컨트롤**:입력 바 내, 모드 셀렉터 우측의 pill(`기억·자동`)을 클릭하면档位 슬라이더가 열립니다(라이트/다크 테마 자적응).
131
+ - 팝오버 하단은 **세션 정보 영역**:회상 히트, 배치 진행, 본 세션 산출 기억 수, 세션 메시지 수에 더해 이상 상태 행(저장소 저하 / 벡터 검색 불가)과 전체 요약.
132
+ - 각 세션 선택은 sessionId 단위로 `session-modes.json`에 영속화되어 재시작/복원에도 유실되지 않습니다.
133
+ - **쓰기 전용(#38)**:팝오버 내 "주입" 3상 스위치(전역 따름 / 켜기 / 끄기)——"끄기"로 **쓰기 전용 세션**:포착과 증류는 평소대로(대화는 L0→L1→L2/L3로 축적)이나 본 세션에는 아무것도 주입되지 않습니다. pill 면문은 `기억·只写`로 변경.
134
+
135
+ ## UI 미리보기
136
+
137
+ <p align="center">
138
+ <img src="./assets/img/ui-dark.jpg" width="49.5%"
139
+ alt="다크 테마 설정 페이지 기억 브라우저 개요">
140
+ <img src="./assets/img/ui-light.jpg" width="49.5%"
141
+ alt="라이트 테마 동일 설정 페이지">
142
+ </p>
143
+
144
+ ## 실측 비교(DSH-MemBench: 자동 벤치마크)
145
+
146
+ "볼거리"에 더해 이 절은 **자동 벤치마크**의 실측 수치로 "**켜면 대체 무엇을 얻는가**"에 답합니다([`bench/`](./bench/), 1명령으로 재현 가능). 방법:동일 시나리오 뱅크·동일 입력으로 **A군(기억 켜기) 3회 병합**, **B군(기억 끄기) 1회**(기억 없는 장작업은 수 배 토큰 소모로 비용 가드레일). 대화 트랙은 A군만.
147
+
148
+ ### 대화 트랙(20 시나리오 × 10형 × 3회 = 420문)
149
+
150
+ > 0.8.5 베이스라인(A군 데이터;대화 트랙 B군은 폐지, A군만).
151
+
152
+ <p align="center">
153
+ <img src="./assets/readme/bench-dialog.svg" width="100%"
154
+ alt="DSH-MemBench 대화 트랙 정확도 도(A군·기억 켜기): 총정확도 95.2%(400/420)">
155
+ </p>
156
+
157
+ **회상 이중 채널**(A군):수동 주입 회상률 **78.1%**(281/360), 나머지는 모델이 **기억 도구를 능동 호출**로 보완(106문이 능동 쿼리, 그중 75문을 도구로 구제). 엔드투엔드 95.2%는 양 채널과 모델 활용의 합성 결과. 기억库가 팽창해도 정확도는 전단 92.8% → 후단 97.7%로 상승, 검색층 recall@5은 합성 노이즈 600건 주입에도 2.8pp만 하락했습니다.
158
+
159
+ **계층별 약점**:검색층 오프라인 지표(recall@5)는 전체 73.3%(이벤트 순서 0%, 장면 회상 50%). **효율 삼각형**(기억의 비용):주입은 지연을 더하지 않고(주입 턴이 평균 210ms 빠름), 주입은 턴당 입력의 약 10.3%, 증류 전체는 포착 메시지 1건당 약 2727 입력 / 240 출력 토큰(1172회 호출·0 실패).
160
+
161
+ ### 워크플로 트랙(0.8.3 보관판)
162
+
163
+ <p align="center">
164
+ <img src="./assets/readme/bench-workflow.svg" width="100%"
165
+ alt="DSH-MemBench 워크플로 트랙 A/B 대조 도">
166
+ </p>
167
+
168
+ **프로브 단계 완료 85.5% vs 43.5%(+42pp)**:3개 신규 프로브 원형(플로 지식 갱신 / 쌍둥이 runbook 구분 / 스타일 규약 계속)에서 A군은 모두 12/12 만점且 3회 일치. B군은 스타일 규약 프로브에서 **0/4**(명명/구조/천단위 구분/푸터 규약은 기억에만 존재).
169
+
170
+ **장작업 비용:B군 세션당 입력 토큰은 A군의 6.8배**(1.81M vs 266k).
171
+
172
+ ### 방법론과 재현
173
+
174
+ ```bash
175
+ node bench/harness/run.mjs --arm A --repeats 3 --provider deepseek-official --model deepseek-v4-flash # 대화 트랙(A군만)
176
+ node bench/harness/run.mjs --track workflow --arm AB --repeats 3 ... # 워크플로 트랙(A/B 병렬)
177
+ node bench/harness/run.mjs --track lifecycle --arm A ... # 라이프사이클 트랙
178
+ node bench/harness/report.mjs --latest [dialog|workflow] # 집계 리포트
179
+ node bench/harness/retrieval-metrics.mjs <runDir> --flood 200,600 # 검색층 지표 + 주입 곡선
180
+ ```
181
+
182
+ 자세한 것은 [`bench/baseline/`](./bench/baseline/) 참조.
183
+
184
+ ## 저장소 레이아웃
185
+
186
+ <p align="center">
187
+ <img src="./assets/readme/storage.svg" width="100%"
188
+ alt="저장소 레이아웃: 이중 기록 아키텍처(JSONL 진실원 + memory.db 검색库)">
189
+ </p>
190
+
191
+ 벡터 기능은 기본 꺼짐(순수 FTS). DSH의 `ctx.llm`에는 embeddings 엔드포인트가 없으며, 의미 검색은 **3상 임베딩 소스**(끄기 / 원격 / 로컬)가 제공합니다. 설정 페이지에서 런타임 전환 가능(다음 절 참조).
192
+
193
+ ## 의미 검색(임베딩 소스)
194
+
195
+ 설정 → 기억 → 개요 → 의미 검색에서 임베딩 소스를 선택, 즉시 반영, 설정 변경·재시작 불필요:
196
+
197
+ <p align="center">
198
+ <img src="./assets/img/EmbeddingSource.png" width="70%"
199
+ alt="설정 페이지 의미 검색(임베딩 소스)패널: 3상 셀렉터(끄기/로컬/원격)">
200
+ </p>
201
+
202
+ 3가지 소스:**끄기**(기본, 순수 BM25 키워드 검색), **원격**(임의의 OpenAI 호환 `/embeddings` 서비스 지참, `embedding.*` 4점 세트가 갖춰지면 선택 가능), **로컬**(내장 모델 카탈로그에서 선택, ONNX 양자화 **CPU 추론**——API Key 불필요, 데이터는 본기에서 나가지 않음). 로컬 카탈로그는 플러그인 내장 허용 목록(각 모델을 revision + 파일별 sha256로 고정, 임의 저장소 다운로드 불가).
203
+
204
+ - **다운로드**:모델 카드 1클릭(기본 미러 `hf-mirror.com`, 재개 대응 + sha256 무결성 검증). 단일 파일 실패는 자동 재시도(캐시 키 변경 `?dshmem-retry=N`).
205
+ - **온디맨드 런타임**:로컬档으로의 첫 전환 시에만 추론 런타임(transformers.js, 약 100〜200MB)을 데이터 디렉터리 `runtime/`에 도입(플러그인 의존 트리·설치 디렉터리에는 손대지 않음). 모델 로드와 추론은 **전용 워커 스레드**에서 실행.
206
+ - **라이브 전환**:1클릭으로 소스 교환——백그라운드 전량 재임베딩(진행 가시·취소 가능, 그 사이 검색은 키워드로 자동 열화, 대화 무영향).
207
+ - **유효 규칙 = 배포 상한 AND 런타임 선택**:`embedding.allowLocalModels=false`로 로컬档 전체 무효화, 미설정이면 원격档 선택 불가(기업 배포에서 수구 가능). 상태는 `embedding-source.json`에 영속화.
208
+
209
+ ## 설정
210
+
211
+ 덮어쓰기 설정은 profile 자신의 `cordis.patch.yml`에 **최상위 수준의 naked patch 항목**으로 작성합니다(직접 `id:` 사용, `insert:`로 감싸지 마세요):
212
+
213
+ ```yaml
214
+ - id: dsh-memory
215
+ name: dsh-prime-memory
216
+ config: # 키는 행 단위 전체 교체(딥 머지 아님)
217
+ family: auto # 새 세션 기본档: auto | chat | work
218
+ llm:
219
+ provider: ''
220
+ model: ''
221
+ ```
222
+
223
+ | 필드 | 기본 | 설명 |
224
+ | --- | --- | --- |
225
+ | `family` | `auto` | 새 세션 기본 기억档:`auto` \| `chat` \| `work` |
226
+ | `dataDir` | `$DSH_HOME/memory` | 데이터 디렉터리 |
227
+ | `capture.enabled` | `true` | L0 포착 |
228
+ | `capture.stripCodeBlocks` | `true` | 어시스턴트 메시지에서 코드 블록 제거 |
229
+ | `capture.maxMessageChars` | `4000` | 단메시지 최대 문자 수 |
230
+ | `extract.enabled` | `true` | L1 추출 |
231
+ | `extract.minMessages` | `6` | 정상 트리거 임계값:단세션이 N건 새 메시지 누적 시 L1 추출 1회. 시작 단계는 1→2→4→…→N 배증 |
232
+ | `extract.idleSeconds` | `300` | 유휴兜底:세션이 N초 무음이면 미증류 슬라이스 투하. `0` 비활성 |
233
+ | `extract.backgroundMessages` | `10` | 추출 시 수반하는 배경 메시지 수 |
234
+ | `extract.candidatePool` | `5` | 중복 제거 후보 풀 크기 |
235
+ | `l2.enabled` | `true` | L2 장면 통합 |
236
+ | `l2.minNewMemories` | `5` | 직전 L2 이후 신규 기억 임계값 |
237
+ | `l2.maxScenes` | `12` | 장면 블록 수 상한 |
238
+ | `l2.sceneContextLimit` | `3` | L2 prompt 수반 유사 장면 전문 상한 |
239
+ | `l3.enabled` | `true` | L3 페르소나 증류 |
240
+ | `l3.interval` | `20` | L3 증류 간격(신규 기억 건수) |
241
+ | `recall.enabled` | `true` | 자동 회상 |
242
+ | `recall.maxResults` | `5` | 각 신규 사용자 메시지 전 주입하는 L1 건수 상한 |
243
+ | `recall.maxCharsPerMemory` | `500` | 주입 기억 1건 문자 상한(초과 잘림). `0` 무제한 |
244
+ | `recall.maxTotalRecallChars` | `2000` | 1회 주입 총 문자 상한. `0` 무제한 |
245
+ | `recall.timeoutMs` | `5000` | 회상 총 예산(ms). 타임아웃은 해당 턴 주입 스킵. `0` 무제한 |
246
+ | `recall.includePersona` | `true` | 시스템 프롬프트에 페르소나 문맥 주입(`<user-persona>`, 안정 영역) |
247
+ | `recall.includeSceneNav` | `true` | 시스템 프롬프트에 장면 내비 주입(`<scene-navigation>`, 안정 영역) |
248
+ | `recall.strategy` | `hybrid` | 검색 전략:`keyword` / `embedding` / `hybrid` |
249
+ | `recall.scoreThreshold` | `0.3` | 회상 점수 임계값(이하 주입 안 함) |
250
+ | `recall.decayHalfLifeDays` | `30` | 회상 신선도 감쇠 반감기(일, `0`=비활성) |
251
+ | `embedding.enabled` | `false` | 벡터 검색 스위치. 끄면 순수 FTS |
252
+ | `embedding.baseUrl` | 빈값 | OpenAI 호환 `/embeddings` 주소 |
253
+ | `embedding.apiKey` | 빈값 | API Key(**원격档은 임의**——로컬 self-host의 무키 `/embeddings`도 허용) |
254
+ | `embedding.model` | 빈값 | 임베딩 모델명 |
255
+ | `embedding.dimensions` | `0` | 벡터 차원(활성 시 필수) |
256
+ | `embedding.maxInputChars` | `5000` | 단텍스트 최대 문자 수(초장 잘림) |
257
+ | `embedding.timeoutMs` | `10000` | 단회 임베딩 호출 타임아웃(ms) |
258
+ | `embedding.allowLocalModels` | `true` | 로컬 임베딩档 허용(배포 상한) |
259
+ | `embedding.mirror` | `https://hf-mirror.com` | 로컬 모델 다운로드 미러 루트 |
260
+ | `embedding.proxy` | `''` | 모델 다운로드 프록시 3상:`''`(기본)= 프록시 환경변수 자동 검출;`none` = 강제 직결 비활성;기타 = 프록시 URL |
261
+ | `llm.provider/model` | 빈값 | 증류 모델 정적 경로(배포 pin):양란 일치 시 잠금 |
262
+ | `llm.fallbacks` | `[]` | 증류 폴백 체인(주 경로 실패 시 순차 시도) |
263
+ | `llm.layerRoutes` | `{}` | **계층별 증류 라우팅**:`l1`/`l2`/`l3` 각 완전 체인 |
264
+ | `llm.maxTokens` | `65536` | 비계층 호출兜底 출력 총闸 |
265
+ | `llm.reasoningEffort` | 빈값 | 증류 사고档位:빈값 = **자동** |
266
+ | `llm.temperature` | `0.3` | 증류 온도 |
267
+ | `llm.maxInputChars` | `700000` | 단회 증류 입력 문자 예산 |
268
+ | `llm.timeoutMs` | `120000` | 단회 증류 호출 타임아웃(ms) |
269
+ | `tokenCost.retentionDays` | `365` | 증류 비용 명세 보존 일수. `0` = 영구 |
270
+ | `tools` | `true` | 모델 호출 가능한 기억 도구 등록 여부 |
271
+ | `benchControl` | `false` | 벤치 제어 서비스 등록(기본 꺼짐) |
272
+
273
+ ### 증류 폴백 체인과 느린 TTFT 모델
274
+
275
+ 일부 공급자의 무료/느린档位는 **첫 토큰 지연(TTFT)이 20초를 넘을** 수 있습니다. 3가지 완화책:
276
+
277
+ 1. **경로 전환**(가장 직접):설정 → 기억 → 개요 → 증류 파라미터의 경로 체인 편집기에서 주 경로 즉시 변경.
278
+ 2. **폴백 체인**(자동 강등):주 경로 실패 시 순차 백업 경로 시도.
279
+ 3. **계층별 라우팅**:L1(고빈도·저렴·안정 중시)과 L3(저빈도·강능력)에 별도 체인.
280
+ 4. **타임아웃 상향**:`llm.timeoutMs`는 경로가 실제로 느리되 게이트웨이가 끊지 않는 경우에만 유효.
281
+
282
+ ## 로그와 문제 해결
283
+
284
+ dsh 호스트는 플러그인 로그를 콘솔로 출력합니다. 플러그인은 info 이상을 데이터 디렉터리의 `memory.log`에도 미러합니다. 1턴의 전형 경로:`L0 포착` → `L0 투하` → `증류 파이프라인 시작` → `LLM 호출` → `L1 단계 완료` → `파이프라인 종료`;다음 턴 머리에 `회상 주입 N건 L1`.
285
+
286
+ ## MemoryCore와의 차이
287
+
288
+ - 완전한 파이프라인 내장(외부 Gateway 비의존), 증류는 DSH 자신의 LLM 재사용;
289
+ - L2/L3를 "LLM이 파일 도구 조작"에서 "LLM이 조작 JSON / 완전 문서 출력, 공학측 실행"으로 변경;
290
+ - 회상 주입점은 `agent/pre-step`(메시지 측 합성 메시지)+ 에이전트 범위 `systemPrompt.context`(페르소나/내비 안정 영역);
291
+ - 저장/검색은 공식 sqlite 백엔드의 단기 슬림판(멀티테넌트 분리열·TCVDB 클라우드 백엔드·감사표 삭제;토큰화는 공식과 동일 jieba 사용).
292
+
293
+ ## 로드맵
294
+
295
+ [Issues](https://github.com/drscrewdriver/dsh-prime-memory/issues)에서 요구와 우선순위 환영:
296
+
297
+ - [ ] **Git 브랜치 인식**:기억을 현재 git 브랜치와 연관, 회상을 브랜치로 필터/가중
298
+ - [ ] **Claude Code / Codex 기억 가져오기**:기존 자산(`CLAUDE.md`, Claude Code 기억 파일, Codex `AGENTS.md` 등)1클릭 이전
299
+
300
+ ## 감사
301
+
302
+ 핵심 기억 능력(계층적 증류 파이프라인, 프롬프트 설계, 이중 기록 저장소)은 [TencentCloud/TencentDB-Agent-Memory](https://github.com/TencentCloud/TencentDB-Agent-Memory)의 **MemoryCore**를 참고했습니다.
303
+
304
+ ## License
305
+
306
+ [MIT](LICENSE)