@a9i5k4/dsh-auto-memory 2.3.0 → 2.3.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.
package/lib/index.js CHANGED
@@ -1750,6 +1750,23 @@ class MemoryEngine {
1750
1750
  return rec && Date.now() - (Number(rec.at) || 0) < 600000 ? rec : null
1751
1751
  }
1752
1752
 
1753
+ /** 2.3.1:解析会话日志文件路径 —— DSH 0.1.5 起会话格式迁移到 `session.v3.jsonl.zstd`
1754
+ * (旧 `session.jsonl.zstd` 保留但停止更新);按 mtime 取最新存在的文件,兼容两代与未来命名。 */
1755
+ async resolveSessionFile(dir) {
1756
+ try {
1757
+ const cands = ['session.v3.jsonl.zstd', 'session.jsonl.zstd', 'session.v3.jsonl', 'session.jsonl']
1758
+ let best = null
1759
+ for (const name of cands) {
1760
+ const p = path.join(dir, name)
1761
+ try {
1762
+ const st = await stat(p)
1763
+ if (st.isFile() && (!best || st.mtimeMs > best.mtimeMs)) best = { path: p, mtimeMs: st.mtimeMs }
1764
+ } catch (e) {}
1765
+ }
1766
+ return best ? best.path : ''
1767
+ } catch (e) { return '' }
1768
+ }
1769
+
1753
1770
  /** 从会话日志(磁盘)推导窗口与模型:不需要 agent,切换会话即可得到正确的模型名与窗口。 */
1754
1771
  async waterWindowForSession(sid) {
1755
1772
  const empty = { window: 0, source: '', model: '', provider: '', contextWindow: 0 }
@@ -1761,7 +1778,8 @@ class MemoryEngine {
1761
1778
  try {
1762
1779
  const dir = await this.locateSessionDir(String(sid))
1763
1780
  if (dir) {
1764
- const raw = await readFile(path.join(dir, 'session.jsonl.zstd')).catch(() => null)
1781
+ const sessionFile = await this.resolveSessionFile(dir)
1782
+ const raw = sessionFile ? await readFile(sessionFile).catch(() => null) : null
1765
1783
  const events = raw ? decodeZstdFrames(raw).split('\n').map((l) => { try { return JSON.parse(l) } catch (e) { return null } }).filter(Boolean) : []
1766
1784
  const info = findSessionModelPre(events)
1767
1785
  const wi = await this.resolveWaterWindow(info.provider, info.model)
@@ -2119,10 +2137,8 @@ class MemoryEngine {
2119
2137
  const sessionsDir = path.join(dshHome(), 'sessions')
2120
2138
  let file = null
2121
2139
  for (const w of await readdir(sessionsDir).catch(() => [])) {
2122
- for (const cand of [path.join(sessionsDir, w, sid, 'session.jsonl.zstd'), path.join(sessionsDir, w, sid, 'session.jsonl')]) {
2123
- try { const st = await stat(cand); if (st.isFile()) { file = cand; break } } catch (e) {}
2124
- }
2125
- if (file) break
2140
+ const resolved = await this.resolveSessionFile(path.join(sessionsDir, w, sid))
2141
+ if (resolved) { file = resolved; break }
2126
2142
  }
2127
2143
  if (!file) return { sessionId: sid }
2128
2144
  const buf = await readFile(file)
@@ -3229,7 +3245,7 @@ class MemoryEngine {
3229
3245
  pending.text,
3230
3246
  '请在本轮回复开头,以「昨日反思 · ' + pending.date + '」小节向用户呈现前一天的工作反思与要点:成果回顾、值得注意的教训或改进、今天可延续的要点。',
3231
3247
  '要求:' + styleText,
3232
- '生成后调用 memory_reflect(date="' + pending.date + '", text=完整反思内容)保存,之后该提示不再出现。',
3248
+ '生成后**必须**调用 memory_reflect(date="' + pending.date + '", text=完整反思内容)保存落盘 —— 只呈现不落盘会导致该提示在后续轮次重复出现。',
3233
3249
  ].join('\n'))
3234
3250
  }
3235
3251
 
@@ -167,9 +167,18 @@ export async function scanPluginSubagentSessions(opts = {}) {
167
167
  out.scanned++
168
168
  const sid = ent.name
169
169
  const dir = path.join(sessionsRoot, wsDir, sid)
170
- const file = path.join(dir, 'session.jsonl.zstd')
170
+ // 2.3.1:DSH 0.1.5 起会话格式迁移到 session.v3.jsonl.zstd(旧名前缀保留但停止更新);
171
+ // 按 mtime 取最新存在的文件,兼容两代命名。
172
+ let file = ''
171
173
  let st = null
172
- try { st = await stat(file) } catch (e) { bump('no-file'); continue }
174
+ for (const name of ['session.v3.jsonl.zstd', 'session.jsonl.zstd']) {
175
+ const cand = path.join(dir, name)
176
+ try {
177
+ const s = await stat(cand)
178
+ if (s.isFile() && (!st || s.mtimeMs > st.mtimeMs)) { st = s; file = cand }
179
+ } catch (e) {}
180
+ }
181
+ if (!st) { bump('no-file'); continue }
173
182
  let text = ''
174
183
  try { text = decodeZstdFrames(await readFile(file)) } catch (e) { bump('decode-error'); continue }
175
184
  const head = parseSessionHead(text)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@a9i5k4/dsh-auto-memory",
3
3
  "description": "Proactive associative memory for DSH: zero-prompt recall injected before the model speaks, three-layer auto-consolidation, skill crystallization, and Astra-style context management - handoff ledgers, PLAN whiteboard, water-level sensing. Local-first, model-agnostic, zero deps. 主动联想记忆+Astra 式上下文管理:自动唤回/自动沉淀/技能固化/交接账本与白板跨窗口续命/水位感知。",
4
- "version": "2.3.0",
4
+ "version": "2.3.1",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {