ultra-memory 3.2.0 → 4.1.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.
@@ -19,6 +19,31 @@ if sys.stderr.encoding != "utf-8":
19
19
 
20
20
  ULTRA_MEMORY_HOME = Path(os.environ.get("ULTRA_MEMORY_HOME", Path.home() / ".ultra-memory"))
21
21
 
22
+ # ── 三层记忆分级 ────────────────────────────────────────────────────────────
23
+ # core: 核心记忆,长期保留,召回优先级最高(里程碑/决策/错误/用户指令)
24
+ # working: 工作记忆,当前会话活跃,定期压缩后可降级为 peripheral
25
+ # peripheral: 外围记忆,历史细节,已压缩,召回时权重最低
26
+
27
+ TIER_CORE = "core"
28
+ TIER_WORKING = "working"
29
+ TIER_PERIPHERAL = "peripheral"
30
+
31
+ CORE_OP_TYPES = {"milestone", "decision", "error", "user_instruction"}
32
+ PERIPHERAL_OP_TYPES = {"file_read", "tool_call"}
33
+
34
+
35
+ def classify_tier(op: dict) -> str:
36
+ """根据操作类型和标签判断记忆层级"""
37
+ op_type = op.get("type", "")
38
+ tags = set(op.get("tags", []))
39
+
40
+ if op_type in CORE_OP_TYPES:
41
+ return TIER_CORE
42
+ # file_read / tool_call 且不含里程碑标签 → 外围
43
+ if op_type in PERIPHERAL_OP_TYPES and "milestone" not in tags:
44
+ return TIER_PERIPHERAL
45
+ return TIER_WORKING
46
+
22
47
 
23
48
  def load_ops(session_dir: Path, only_uncompressed: bool = True) -> list[dict]:
24
49
  ops_file = session_dir / "ops.jsonl"
@@ -38,7 +63,7 @@ def load_ops(session_dir: Path, only_uncompressed: bool = True) -> list[dict]:
38
63
 
39
64
 
40
65
  def mark_compressed(session_dir: Path, up_to_seq: int):
41
- """标记已压缩的操作(不删除,只打标记)"""
66
+ """标记已压缩的操作(不删除,打标记 + 写入 tier 分层)"""
42
67
  ops_file = session_dir / "ops.jsonl"
43
68
  tmp_file = session_dir / "ops.jsonl.tmp"
44
69
  with open(ops_file, encoding="utf-8") as fin, open(tmp_file, "w", encoding="utf-8") as fout:
@@ -49,6 +74,9 @@ def mark_compressed(session_dir: Path, up_to_seq: int):
49
74
  op = json.loads(line)
50
75
  if op["seq"] <= up_to_seq:
51
76
  op["compressed"] = True
77
+ # 写入 tier(若尚未分级)
78
+ if "tier" not in op:
79
+ op["tier"] = classify_tier(op)
52
80
  fout.write(json.dumps(op, ensure_ascii=False) + "\n")
53
81
  tmp_file.replace(ops_file)
54
82
 
@@ -207,6 +235,15 @@ def generate_summary_md(session_id: str, ops: list[dict], meta: dict) -> str:
207
235
  lines.append(f"- 主要领域: {', '.join(top_tags)}")
208
236
  lines.append("")
209
237
 
238
+ # 记忆分层统计
239
+ tier_counts: Counter = Counter(classify_tier(op) for op in ops)
240
+ if any(tier_counts.values()):
241
+ lines.append("## 🧠 记忆分层")
242
+ lines.append(f"- core(核心): {tier_counts[TIER_CORE]} 条 — 长期保留,高召回优先级")
243
+ lines.append(f"- working(工作): {tier_counts[TIER_WORKING]} 条 — 当前会话活跃")
244
+ lines.append(f"- peripheral(外围): {tier_counts[TIER_PERIPHERAL]} 条 — 历史细节,低优先级")
245
+ lines.append("")
246
+
210
247
  # 操作日志范围(供下次恢复参考)
211
248
  lines.append("## 📋 操作日志范围")
212
249
  lines.append(f"ops.jsonl {op_range}(已压缩,原始记录保留)")