dsh-layered-memory 0.6.1 → 0.7.1

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 (49) hide show
  1. package/README.en.md +106 -81
  2. package/README.md +93 -80
  3. package/assets/img/Hero.png +0 -0
  4. package/assets/img/Layers.png +0 -0
  5. package/assets/img/Modes.png +0 -0
  6. package/assets/img/ui-dark.jpg +0 -0
  7. package/assets/img/ui-light.jpg +0 -0
  8. package/assets/readme/flow.svg +189 -0
  9. package/assets/readme/storage.svg +115 -0
  10. package/dist/client.js +1100 -402
  11. package/dist/config.d.ts +12 -0
  12. package/dist/config.js +20 -17
  13. package/dist/hooks/capture.d.ts +17 -1
  14. package/dist/hooks/capture.js +45 -11
  15. package/dist/hooks/recall.d.ts +7 -0
  16. package/dist/hooks/recall.js +20 -4
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.js +107 -44
  19. package/dist/pipeline/rebuild.d.ts +2 -0
  20. package/dist/pipeline/rebuild.js +7 -0
  21. package/dist/pipeline/runner.d.ts +7 -1
  22. package/dist/pipeline/runner.js +22 -7
  23. package/dist/runtime-package-lock.json +982 -0
  24. package/dist/settings.js +79 -20
  25. package/dist/stats.d.ts +7 -1
  26. package/dist/stats.js +131 -14
  27. package/dist/store/download-queue.d.ts +71 -0
  28. package/dist/store/download-queue.js +313 -0
  29. package/dist/store/embedding-source.d.ts +160 -0
  30. package/dist/store/embedding-source.js +421 -0
  31. package/dist/store/embedding.d.ts +3 -1
  32. package/dist/store/embedding.js +5 -0
  33. package/dist/store/l0.d.ts +13 -5
  34. package/dist/store/l0.js +40 -10
  35. package/dist/store/l1.d.ts +15 -5
  36. package/dist/store/l1.js +47 -19
  37. package/dist/store/local-embedding.d.ts +64 -0
  38. package/dist/store/local-embedding.js +120 -0
  39. package/dist/store/model-catalog.d.ts +45 -0
  40. package/dist/store/model-catalog.js +78 -0
  41. package/dist/store/runtime-installer.d.ts +65 -0
  42. package/dist/store/runtime-installer.js +220 -0
  43. package/dist/store/sqlite.d.ts +68 -7
  44. package/dist/store/sqlite.js +422 -73
  45. package/dist/tools/index.js +6 -4
  46. package/dist/util/filelog.d.ts +2 -0
  47. package/dist/util/filelog.js +20 -3
  48. package/package.json +1 -1
  49. package/assets/readme/hero.svg +0 -58
@@ -32,6 +32,8 @@ export class MemoryRunner {
32
32
  live;
33
33
  tasks = [];
34
34
  draining = false;
35
+ /** 停止标志(dispose 序置位):不再取新任务;进行中任务自然收尾,其 DB 写入失败由各层兜底捕获。 */
36
+ stopped = false;
35
37
  pending = emptyPending();
36
38
  pendingFile;
37
39
  background = [];
@@ -104,7 +106,13 @@ export class MemoryRunner {
104
106
  runRebuildTurn(sessionId, messages) {
105
107
  return this.runTurn(sessionId, messages, 'auto', { noBufferCap: true });
106
108
  }
109
+ /** 停止取新任务(插件 dispose 序调用;进行中任务照常跑完但不 await——LLM 慢调用不拖住宿主卸载)。 */
110
+ stop() {
111
+ this.stopped = true;
112
+ }
107
113
  pushTask(task) {
114
+ if (this.stopped)
115
+ return;
108
116
  this.tasks.push(task);
109
117
  void this.drain();
110
118
  }
@@ -113,7 +121,7 @@ export class MemoryRunner {
113
121
  return;
114
122
  this.draining = true;
115
123
  try {
116
- while (this.tasks.length > 0) {
124
+ while (!this.stopped && this.tasks.length > 0) {
117
125
  const [task] = this.tasks.splice(pickNextTaskIndex(this.tasks), 1);
118
126
  try {
119
127
  await task.run();
@@ -127,9 +135,18 @@ export class MemoryRunner {
127
135
  this.draining = false;
128
136
  }
129
137
  }
130
- /** 缓冲落盘(每次蒸馏尝试后调用;失败只告警不阻断管线)。 */
131
- async persistPending() {
138
+ /** 缓冲落盘(每次蒸馏尝试后调用;失败只告警不阻断管线)。
139
+ * 非重建轮持久化前按桶截断到上限:重建取消后的大桶不至于在后续每次
140
+ * 蒸馏尝试时反复整量序列化落盘(多 MB 级 IO);重建轮豁免维持。 */
141
+ async persistPending(noBufferCap = false) {
132
142
  try {
143
+ if (!noBufferCap) {
144
+ for (const key of PENDING_MODES) {
145
+ const bucket = this.pending[key];
146
+ if (bucket.length > PENDING_BUCKET_CAP)
147
+ this.pending[key] = bucket.slice(-PENDING_BUCKET_CAP);
148
+ }
149
+ }
133
150
  await savePending(this.pendingFile, this.pending);
134
151
  }
135
152
  catch (err) {
@@ -161,13 +178,11 @@ export class MemoryRunner {
161
178
  this.logger.info(`[memory] L1 阶段完成(${Date.now() - t}ms)`);
162
179
  }
163
180
  catch (err) {
164
- // 保留 pending,下次重试;但防止无限堆积(重建轮不限,量被会话规模天然约束)
165
- if (!opts?.noBufferCap && this.pending[mode].length > PENDING_BUCKET_CAP)
166
- this.pending[mode] = [];
181
+ // 保留 pending 下次重试(runTurn 入口已裁到 ≤200,防无限堆积;重建轮不裁,量被会话规模约束)
167
182
  this.logger.warn(`[memory] L1 抽取失败(mode=${mode},pending=${this.pending[mode].length}): ${errDetail(err)}`);
168
183
  }
169
184
  // 缓冲每次尝试后立即落盘:进程中途退出不丢待重试/攒阈值状态
170
- await this.persistPending();
185
+ await this.persistPending(opts?.noBufferCap);
171
186
  // L1 计数推进后立即落盘:L2/L3 失败或进程中途退出不得回滚阈值进度
172
187
  // (记录已入库但计数丢失会让该族 L2 永远差一截,state 与 DB 脱节)
173
188
  try {