Skill: laojun509/memcore (version 0.2.0)

# MemCore Enhanced - 增强版五层记忆系统 > 基于原版 MemCore，新增四大核心功能：情景记忆、语义压缩、记忆触发器、遗忘曲线 ## 架构概览 ``` ┌─────────────────────────────────────────────────────┐ │ Context Memory - 当前对话 (秒-分钟级) │ 原有 │ (滑动窗口 + Token限制) │ ├─────────────────────────────────────────────────────┤ │ Task Memory - 任务状态 (分钟-小时级) │ 原有 │ (状态机管理) │ ├─────────────────────────────────────────────────────┤ │ User Memory - 用户偏好 (持久化) │ 原有 │ (版本控制) │ ├─────────────────────────────────────────────────────┤ │ Knowledge Memory - 外部知识 (持久化) │ 原有 │ (向量检索) │ ├─────────────────────────────────────────────────────┤ │ Experience Memory - 执行历史 (长期) │ 原有 │ (强化学习) │ ├─────────────────────────────────────────────────────┤ │ ✨ 新增四大功能 │ 增强 ├─────────────────────────────────────────────────────┤ │ Episodic Memory - 情景记忆 (事件/结论) │ ✓ 新增 │ (上次讨论X时，结论是Y) │ ├─────────────────────────────────────────────────────┤ │ Semantic - 语义压缩 │ ✓ 新增 │ Compression (10条→1条摘要) │ ├─────────────────────────────────────────────────────┤ │ Memory Triggers - 记忆触发器 │ ✓ 新增 │ (关键词→自动加载相关记忆) │ ├─────────────────────────────────────────────────────┤ │ Forgetting Curve - 遗忘曲线 │ ✓ 新增 │ (艾宾浩斯遗忘模型) │ └─────────────────────────────────────────────────────┘ │ 🔧 额外增强功能 │ ├─────────────────────────────────────────────────────┤ │ Persistent Storage - SQLite持久化 │ ✓ 新增 │ Vector Knowledge - 向量语义检索 │ ✓ 新增 │ Conflict Resolver - 智能冲突解决 │ ✓ 新增 │ Confidence Tracker - 记忆置信度跟踪 │ ✓ 新增 └─────────────────────────────────────────────────────┘ ``` ## 快速开始 ### 安装依赖 ```bash pip install numpy ``` ### 基本使用 ```python from memcore_enhanced import MemCoreEnhanced, MemoryPriority, MemorySource # 初始化（启用持久化） mc = MemCoreEnhanced(db_path="~/.memcore/memory.db") # 记录情景记忆 episode_id = mc.record_episode( episode_type="discussion", context_summary="用户询问优化建议", conclusion="建议添加四个新功能", related_topics=["MemCore", "AI记忆"], priority=MemoryPriority.HIGH, confidence=1.0, source=MemorySource.EXPLICIT ) # 查询时触发相关记忆 result = mc.process_input("我想继续弄MemCore") print(result['suggested_context']) ``` ## 核心功能详解 ### 1. Episodic Memory (情景记忆) 记录具体事件和结论，支持自然语言回忆。 ```python # 记录情景 mc.record_episode( episode_type="discussion", # discussion | decision | event context_summary="用户询问优化建议", conclusion="建议添加四个模块", related_topics=["MemCore", "AI记忆"], participants=["user", "assistant"], priority=MemoryPriority.HIGH ) # 回忆相关情景 episodes = mc.recall_episodes(topic="MemCore", limit=5) for ep in episodes: print(ep.to_natural_language()) # 输出: [2025-01-13 14:30] discussion: 关于 '用户询问优化建议' 的讨论，结论是：建议添加四个模块 ``` ### 2. Semantic Compression (语义压缩) 自动压缩冗余信息，保持上下文窗口精简。 ```python # 添加大量对话上下文 for msg in conversation: mc.add_to_context(msg) # 超过20条消息时自动触发压缩 mc.compress_memories("context") # 压缩后保留: [最近2条, {摘要}] ``` ### 3. Memory Triggers (记忆触发器) 关键词触发，自动加载相关背景。 ```python # 创建触发器（也会自动根据情景记忆创建） mc.create_trigger( keywords=["项目X", "Project X"], target_memory_ids=["ep_abc123", "user_pref_456"] ) # 处理用户输入 result = mc.process_input("我想继续搞项盯x") # 返回: { # "triggered": True, # "loaded_memories": [...], # "suggested_context": "...", # "related_knowledge": [...] # } ``` ### 4. Forgetting Curve (遗忘曲线) 模拟艾宾浩斯遗忘曲线，智能清理低价值记忆。 ```python # 运行遗忘周期（通常每天运行一次） result = mc.run_forgetting_cycle() # 返回: { # "checked": 100, # 检查的记忆数 # "deleted": 5, # 删除的记忆数 # "deleted_ids": [...] # } # 查看记忆健康报告 health = mc.get_health_report() ``` **Forgetting Score 计算:** ``` 9057忘分数 = 1 - R(t) R(t) = e^(-t/S) + 最近访问奖励 - 压缩惩罚 S = 优先级 × (1 + 访问次数 × 0.1) # 记忆强度 ``` ### 5. Persistent Storage (持久化存储) SQLite 数据库持久化存储，支持跨会话记忆。 ```python # 初始化时指定数据库路径 mc = MemCoreEnhanced(db_path="~/.memcore/memory.db") # 所有操作自动持久化 # - 情景记忆 # - 用户偏好 # - 触发器 # - 任务状态 # 重启后自动恢复 mc2 = MemCoreEnhanced(db_path="~/.memcore/memory.db") # 所有记忆已加载 ``` ### 6. Vector Knowledge (向量知识检索) 语义相似度检索，无需精确关键词匹配。 ```python # 添加知识 mc.add_knowledge( content="MemCore 采用五层记忆架构", metadata={"topics": ["architecture", "MemCore"]}, source="docs" ) # 语义查询 results = mc.query_knowledge("记忆系统怎么设计的？") # 返回高相似度结果，即使关键词不完全匹配 ``` 支持外部 Embedding 模型： ```python from vector_knowledge import OpenAIEmbeddingWrapper mc = MemCoreEnhanced( embedding_fn=OpenAIEmbeddingWrapper([REDACTED_SECRET]") ) ``` ### 7. Conflict Resolution (记忆冲突解决) 自动检测并解决新旧记忆矛盾。 ```python # 当记录新记忆时自动检测冲突 mc.record_episode( context_summary="用户偏好", conclusion="用户喜欢Python" ) mc.record_episode( context_summary="用户偏好", conclusion="用户讨厌Python" # 检测到矛盾！ ) # 解决策略: # - TIME_PRIORITY: 新的覆盖旧的 # - CONFIDENCE_PRIORITY: 高置信度优先 # - MERGE: 尝试合并 # - KEEP_BOTH: 保留两者 ``` ### 8. Confidence Tracking (记忆置信度跟踪) 每条记忆都有置信度和来源溯源。 ```python # 注册时指定来源和置信度 mc.record_episode( context_summary="用户告知姓名", conclusion="用户叫露丝", confidence=1.0, source=MemorySource.EXPLICIT # 用户明确说的 ) # 用户验证增加置信度 mc.confidence_tracker.verify("ep_xxx", verifier="user") # 用户否认降低置信度 mc.confidence_tracker.contradict("ep_xxx", reason="姓名错误") # 查看置信度报告 report = mc.confidence_tracker.get_confidence_report("ep_xxx") # { # "effective_confidence": 0.95, # "trust_level": "💚 高度可信" # } ``` ## 高级使用 ### 与原版 MemCore 兼容 ```python # 也可以单独使用原有层 from memcore_enhanced import ContextMemory, TaskMemory, UserMemory context = ContextMemory(max_messages=20, max_tokens=4000) context.add_message("user", "Hello") messages = context.get_context() ``` ### 用户偏好管理 ```python # 更新用户偏好 mc.update_user_preference( user_id="user_123", key="response_style", value="concise", confidence=1.0, source=MemorySource.EXPLICIT ) # 查询用户偏好 prefs = mc.backend.load_user_memory("user_123") ``` ### 健康监控 ```python # 获取系统健康报告 health = mc.get_health_report() # { # "episodic_memory": {"count": 100, "by_priority": {...}}, # "triggers": {"count": 20, "total_triggered": 150}, # "knowledge": {...}, # "database": {...} # } # 查看低置信度记忆 low_conf = mc.confidence_tracker.get_low_confidence_memories(threshold=0.5) ``` ## API 参考 ### MemCoreEnhanced 主要类，提供统一入口。 **Methods:** - `record_episode(...)` - 记录情景 - `recall_episodes(...)` - 回忆情景 - `create_trigger(...)` - 创建触发器 - `process_input(text)` - 处理输入 - `add_knowledge(...)` - 添加知识 - `query_knowledge(...)` - 查询知识 - `run_forgetting_cycle()` - 运行遗忘 - `get_health_report()` - 健康报告 ### 枚举类 **MemoryPriority:** `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, `EPHEMERAL` **MemorySource:** `EXPLICIT`, `IMPLICIT`, `INFERRED`, `IMPORTED`, `DERIVED` **ConflictStrategy:** `TIME_PRIORITY`, `CONFIDENCE_PRIORITY`, `MERGE`, `KEEP_BOTH`, `MANUAL_REVIEW` ## 性能指标 | 操作 | 复杂度 | |------|--------| | 记录情景 | O(1) | | 回忆查询 | O(n) | | 触发器检查 | O(m×k) | | 向量检索 | O(n) | | 数据库查询 | O(log n) | ## 版本历史 - **v0.2.0** - 增强版 - 新增情景记忆 - 新增语义压缩 - 新增记忆触发器 - 新增遗忘曲线 - 新增SQLite持久化 - 新增向量检索 - 新增冲突解决 - 新增置信度跟踪 - **v0.1.0** - 原版 - 五层记忆架构 ## 贡献者 - 原版架构: [@laojun509](https://clawhub.ai/laojun509/memcore) - 增强版协助: Hermes Agent (露丝) ## 许可证 MIT-0 - 完全开源，可自由使用、修改和分发

path: README.md
content: # Enhanced MemCore

> 基于原版 MemCore 的完整增强版本，新增 8 大功能模块

---

## 架构图

```
┌────────────────────────────────────────────────┐
│         MemCoreEnhanced (Central Router)          │
├────────────────────────────────────────────────┤
│                                                    │
│  📕 原版五层记忆                                    │
│  ┌─────────────────────────────────────┐         │
│  │ Context Memory  (秒-分钟级)    │         │
│  │ Task Memory     (任务状态)      │         │
│  │ User Memory     (用户偏好)     │         │
│  │ Knowledge Memory(知识库)       │         │
│  │ Experience Memory(经验学习)   │         │
│  └─────────────────────────────────────┘         │
│                                                    │
│  🆕 新增四层记忆                                    │
│  ┌─────────────────────────────────────┐         │
│  │ Episodic Memory  (情景/事件)   │         │
│  │ Semantic Compress(语义压缩)   │         │
│  │ Memory Triggers  (触发器)      │         │
│  │ Forgetting Curve (遗忘曲线)    │         │
│  └─────────────────────────────────────┘         │
│                                                    │
│  🔧 增强功能模块                                    │
│  ┌─────────────────────────────────────┐         │
│  │ 💾 Persistent Storage (SQLite)   │         │
│  │ 🔢 Vector Knowledge(向量检索)  │         │
│  │ ⚖️ Conflict Resolver(冲突解决)│         │
│  │ 📊 Confidence Tracker(置信度)  │         │
│  └─────────────────────────────────────┘         │
│                                                    │
└────────────────────────────────────────────────┘
```

---

## 文件结构

```
memcore-enhanced/
├── enhanced_memcore.py       # 基础类定义
├── persistent_backend.py    # SQLite 持久化
├── vector_knowledge.py      # 向量检索
├── conflict_resolver.py     # 冲突解决
├── confidence_tracker.py    # 置信度跟踪
├── memcore_enhanced.py      # 整合主模块
├── SKILL.md                 # 使用文档
└── README.md                # 本文件
```

---

## 功能详解

### 1. Episodic Memory (情景记忆)

记录具体事件和结论：

```python
mc = MemCoreEnhanced()

# 记录情景
episode_id = mc.record_episode(
    context_summary="用户询问 MemCore 优化",
    conclusion="建议添加四个新模块",
    related_topics=["MemCore", "AI记忆"],
    priority=MemoryPriority.HIGH
)

# 自然语言输出
print(mc.episodic_memory[episode_id].to_natural_language())
# [2026-01-13 10:00] discussion: 关于 '用户询问 MemCore 优化' 的讨论，结论是：建议添加四个新模块

# 按主题回忆
episodes = mc.recall_episodes(topic="MemCore")
```

### 2. Semantic Compression (语义压缩)

自动压缩冗余信息：

```python
# 添加大量上下文
for msg in conversation:
    mc.context_memory.append(msg)

# 超过阈值时自动触发压缩
mc.compress_memories("context")
# 压缩后: [最近2条消息, {摘要}]
```

### 3. Memory Triggers (记忆触发器)

关键词自动触发记忆加载：

```python
# 创建触发器
mc.create_trigger(
    keywords=["项目X", "Project X"],
    target_memory_ids=["ep_abc123"]
)

# 用户输入触发
result = mc.process_input("我想继续搞项盯x")
# result['loaded_memories'] 自动包含相关记忆
```

### 4. Forgetting Curve (遗忘曲线)

模拟艾宾浩斯遗忘曲线：

```python
# 运行遗忘周期
result = mc.run_forgetting_cycle()
# 自动删除低优先级且长时间未访问的记忆

# 遗忘分数计算（基于）：
# - 记忆年龄
# - 访问频率
# - 优先级
# - 压缩次数
```

### 5. Persistent Storage (持久化存储)

SQLite 数据库持久化：

```python
mc = MemCoreEnhanced(db_path="~/.memcore/memory.db")

# 所有操作自动持久化
mc.record_episode(...)  # 自动写入数据库
mc.update_user_preference(...)  # 自动保存

# 重启后自动恢复
mc2 = MemCoreEnhanced(db_path="~/.memcore/memory.db")
# 所有记忆已加载
```

支持的表：
- `episodic_memory` - 情景记忆
- `user_memory` - 用户偏好
- `memory_triggers` - 触发器
- `task_memory` - 任务状态
- `knowledge_memory` - 知识库

### 6. Vector Knowledge (向量检索)

语义相似度检索：

```python
# 添加知识
mc.add_knowledge(
    content="MemCore 使用五层记忆架构",
    metadata={"topics": ["architecture"]},
    source="docs"
)

# 语义查询（不需精确关键词匹配）
results = mc.query_knowledge("记忆系统是怎么设计的？")
# 返回高相似度结果
```

支持外部 Embedding 模型（如 OpenAI）：

```python
from vector_knowledge import OpenAIEmbeddingWrapper

mc = MemCoreEnhanced(
    embedding_fn=OpenAIEmbeddingWrapper([REDACTED_SECRET]")
)
```

### 7. Conflict Resolution (冲突解决)

自动检测并解决记忆冲突：

```python
# 自动检测冲突
mc.record_episode(
    context_summary="用户偏好",
    conclusion="用户喜欢 Python"
)

mc.record_episode(
    context_summary="用户偏好",
    conclusion="用户讨厌 Python"  # 检测到矛盾！
)

# 解决策略：
# - TIME_PRIORITY: 新的覆盖旧的
# - CONFIDENCE_PRIORITY: 高置信度优先
# - MERGE: 尝试合并
# - KEEP_BOTH: 保留两者
```

### 8. Confidence Tracking (置信度跟踪)

每条记忆都有置信度和来源溯源：

```python
# 注册记忆时指定来源和置信度
mc.record_episode(
    context_summary="用户告知姓名",
    conclusion="用户名字是露丝",
    confidence=1.0,  # 用户明确说的
    source=MemorySource.EXPLICIT
)

# 用户验证增加置信度
mc.confidence_tracker.verify("ep_xxx", verifier="user")

# 用户否认降低置信度
mc.confidence_tracker.contradict("ep_xxx", reason="姓名错误")

# 查看置信度报告
report = mc.confidence_tracker.get_confidence_report("ep_xxx")
# {
#   "effective_confidence": 0.95,
#   "verification_count": 2,
#   "trust_level": "💚 高度可信"
# }
```

---

## 安装

```bash
pip install numpy  # 向量计算需要
# 可送: pip install openai  # 如果使用 OpenAI Embedding
```

---

## 快速开始

```python
from memcore_enhanced import MemCoreEnhanced, MemoryPriority, MemorySource

# 初始化
mc = MemCoreEnhanced(db_path="~/.memcore/my_memory.db")

# 记录情景
mc.record_episode(
    context_summary="用户给我起名字",
    conclusion="用户喜欢叫我'露丝'",
    related_topics=["用户信息", "名字"],
    priority=MemoryPriority.CRITICAL,
    source=MemorySource.EXPLICIT
)

# 添加知识
mc.add_knowledge(
    content="MemCore 是五层记忆架构的 AI 记忆系统",
    source="github"
)

# 处理输入（触发记忆）
result = mc.process_input("你好，我是露丝")
print(result['suggested_context'])

# 健康报告
print(mc.get_health_report())
```

---

## 性能指标

| 指标 | 数值 |
|------|------|
| 情景记忆查询 | O(n) |
| 向量检索 | O(n) |
| 触发器检查 | O(m*k) m=触发器数, k=关键词数 |
| 数据库查询 | O(log n) 有索引 |
| 遗忘分数计算 | O(1) |

---

## 贡献

- 原版 MemCore: [@laojun509](https://clawhub.ai/laojun509/memcore)
- 增强功能设计: 社区反馈 + Hermes Agent (露丝)

## 许可证

MIT-0 - 完全开源，无需声明


path: __init__.py
content: """
MemCore Enhanced - 增强版五层记忆系统
=====================================

基于原版 MemCore，新增四大功能：
- Episodic Memory (情景记忆)
- Semantic Compression (语义压缩)
- Memory Triggers (记忆触发器)
- Forgetting Curve (遗忘曲线)

额外增强：
- Persistent Storage (SQLite持久化)
- Vector Knowledge (向量检索)
- Conflict Resolution (冲突解决)
- Confidence Tracking (置信度跟踪)

作者: laojun509 (增强版协助: Hermes Agent)
版本: 0.2.0
许可证: MIT-0
"""

__version__ = "0.2.0"
__author__ = "laojun509"

# 导出核心类
from .memcore_enhanced import MemCoreEnhanced
from .enhanced_memcore import (
    EpisodicMemoryEntry,
    MemoryTrigger,
    SemanticCompressor,
    ForgettingCurveManager,
    MemoryPriority
)
from .confidence_tracker import MemorySource, ConfidenceMetrics
from .conflict_resolver import ConflictStrategy, MemoryConflict

# 使用示例
def quickstart():
    """快速开始示例"""
    print("""
    from memcore_enhanced import MemCoreEnhanced, MemoryPriority
    
    mc = MemCoreEnhanced()
    
    # 记录情景
    mc.record_episode(
        context_summary="用户询问优化建议",
        conclusion="建议添加四个模块",
        related_topics=["MemCore"],
        priority=MemoryPriority.HIGH
    )
    
    # 触发记忆
    result = mc.process_input("我想继续弄MemCore")
    print(result['suggested_context'])
    """)

__all__ = [
    'MemCoreEnhanced',
    'EpisodicMemoryEntry',
    'MemoryTrigger',
    'SemanticCompressor',
    'ForgettingCurveManager',
    'MemoryPriority',
    'MemorySource',
    'ConfidenceMetrics',
    'ConflictStrategy',
    'MemoryConflict',
    'quickstart'
]


path: confidence_tracker.py
content: """
Confidence Tracking for Enhanced MemCore
记忆置信度跟踪系统
每条记忆都有可置信度和来源溯源
"""

from typing import Dict, List, Any, Optional, Callable
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum


class MemorySource(Enum):
    """记忆来源类型"""
    EXPLICIT = "explicit"           # 用户明确说的
    IMPLICIT = "implicit"           # 系统推断的
    INFERRED = "inferred"           # 基于上下文推断
    IMPORTED = "imported"           # 从外部导入
    DERIVED = "derived"             # 派生自其他记忆


@dataclass
class MemoryProvenance:
    """记忆溯源信息"""
    source: MemorySource
    original_query: Optional[str] = None  # 原始用户查询
    extraction_method: str = ""           # 提取方法
    parent_memory_id: Optional[str] = None  # 父记忆ID
    created_by: str = "system"            # 创建者
    chain_of_thought: List[str] = field(default_factory=list)  # 推理链
    verification_history: List[Dict] = field(default_factory=list)


@dataclass
class ConfidenceMetrics:
    """置信度指标"""
    base_confidence: float = 1.0           # 基础置信度
    verification_count: int = 0          # 验证次数
    contradiction_count: int = 0         # 被质疑次数
    access_count: int = 0                # 被使用次数
    last_verified: Optional[datetime] = None
    stability_score: float = 1.0         # 稳定性分数
    
    @property
    def effective_confidence(self) -> float:
        """计算有效置信度"""
        # 验证次数加成
        verification_bonus = min(self.verification_count * 0.1, 0.3)
        
        # 矛盾惩罚
        contradiction_penalty = min(self.contradiction_count * 0.2, 0.5)
        
        # 时间衰减（如果很久没验证）
        time_penalty = 0
        if self.last_verified:
            days_since = (datetime.now() - self.last_verified).days
            time_penalty = min(days_since * 0.01, 0.2)
        
        confidence = self.base_confidence + verification_bonus - contradiction_penalty - time_penalty
        return max(0.1, min(1.0, confidence))  # 限制在 0.1-1.0


class ConfidenceTracker:
    """
    记忆置信度跟踪器
    负责：
    1. 记录来源
    2. 跟踪验证
    3. 计算置信度
    4. 提供溯源链
    """
    
    def __init__(self):
        self.provenance_store: Dict[str, MemoryProvenance] = {}
        self.confidence_store: Dict[str, ConfidenceMetrics] = {}
    
    def register_memory(
        self,
        memory_id: str,
        source: MemorySource,
        base_confidence: float = 1.0,
        **metadata
    ) -> ConfidenceMetrics:
        """
        注册新记忆的溯源信息
        
        Args:
            memory_id: 记忆唯一ID
            source: 来源类型
            base_confidence: 基础置信度
            **metadata: 额外元数据
        """
        # 创建溯源记录
        provenance = MemoryProvenance(
            source=source,
            original_query=metadata.get('original_query'),
            extraction_method=metadata.get('extraction_method', 'direct'),
            parent_memory_id=metadata.get('parent_memory_id'),
            created_by=metadata.get('created_by', 'system'),
            chain_of_thought=metadata.get('chain_of_thought', [])
        )
        self.provenance_store[memory_id] = provenance
        
        # 创建置信度指标
        metrics = ConfidenceMetrics(
            base_confidence=base_confidence,
            verification_count=0,
            contradiction_count=0
        )
        self.confidence_store[memory_id] = metrics
        
        return metrics
    
    def verify(self, memory_id: str, verifier: str = "user", notes: str = ""):
        """
        验证记忆（增加置信度）
        
        Args:
            memory_id: 记忆ID
            verifier: 验证者
            notes: 验证注释
        """
        if memory_id not in self.confidence_store:
            return
        
        metrics = self.confidence_store[memory_id]
        metrics.verification_count += 1
        metrics.last_verified = datetime.now()
        
        # 记录验证历史
        if memory_id in self.provenance_store:
            self.provenance_store[memory_id].verification_history.append({
                'timestamp': datetime.now().isoformat(),
                'verifier': verifier,
                'notes': notes
            })
    
    def contradict(self, memory_id: str, reason: str = ""):
        """
        质疑/否定记忆（降低置信度）
        """
        if memory_id not in self.confidence_store:
            return
        
        metrics = self.confidence_store[memory_id]
        metrics.contradiction_count += 1
        metrics.stability_score *= 0.8  # 稳定性下降
        
        if memory_id in self.provenance_store:
            self.provenance_store[memory_id].verification_history.append({
                'timestamp': datetime.now().isoformat(),
                'verifier': 'user',
                'notes': f"被质疑: {reason}",
                'type': 'contradiction'
            })
    
    def get_confidence(self, memory_id: str) -> float:
        """获取记忆的有效置信度"""
        if memory_id not in self.confidence_store:
            return 0.5  # 未知记忆给中等置信度
        
        return self.confidence_store[memory_id].effective_confidence
    
    def get_provenance(self, memory_id: str) -> Optional[MemoryProvenance]:
        """获取记忆溯源"""
        return self.provenance_store.get(memory_id)
    
    def get_confidence_report(self, memory_id: str) -> Dict[str, Any]:
        """获取详细的置信度报告"""
        if memory_id not in self.confidence_store:
            return {"error": "Memory not found"}
        
        metrics = self.confidence_store[memory_id]
        provenance = self.provenance_store.get(memory_id)
        
        return {
            'memory_id': memory_id,
            'effective_confidence': metrics.effective_confidence,
            'base_confidence': metrics.base_confidence,
            'verification_count': metrics.verification_count,
            'contradiction_count': metrics.contradiction_count,
            'stability_score': metrics.stability_score,
            'source': provenance.source.value if provenance else 'unknown',
            'extraction_method': provenance.extraction_method if provenance else 'unknown',
            'verification_history': provenance.verification_history if provenance else [],
            'trust_level': self._categorize_trust(metrics.effective_confidence)
        }
    
    def _categorize_trust(self, confidence: float) -> str:
        """将置信度分类为信任等级"""
        if confidence >= 0.9:
            return "💚 高度可信 (High Trust)"
        elif confidence >= 0.7:
            return "💛 可信 (Trusted)"
        elif confidence >= 0.5:
            return "💚 需要验证 (Needs Verification)"
        else:
            return "🔴 可疑 (Questionable)"
    
    def export_provenance_chain(self, memory_id: str) -> List[Dict]:
        """
        导出溯源链（追溯到原始来源）"""
        chain = []
        current_id = memory_id
        
        while current_id:
            provenance = self.provenance_store.get(current_id)
            if not provenance:
                break
            
            metrics = self.confidence_store.get(current_id)
            chain.append({
                'memory_id': current_id,
                'source': provenance.source.value,
                'confidence': metrics.effective_confidence if metrics else 0,
                'extraction_method': provenance.extraction_method
            })
            
            current_id = provenance.parent_memory_id
        
        return list(reversed(chain))  # 从原始到当前
    
    def get_low_confidence_memories(self, threshold: float = 0.5) -> List[str]:
        """获取低置信度的记忆ID列表"""
        low_conf = []
        for mem_id, metrics in self.confidence_store.items():
            if metrics.effective_confidence < threshold:
                low_conf.append(mem_id)
        return low_conf


# 测试代码
if __name__ == "__main__":
    print("🧠 测试 Confidence Tracker...")
    
    tracker = ConfidenceTracker()
    
    # 注册新记忆
    print("\n✅ 注册记忆...")
    tracker.register_memory(
        memory_id="mem_001",
        source=MemorySource.EXPLICIT,
        base_confidence=1.0,
        extraction_method="user_input",
        original_query="我叫露丝"
    )
    
    tracker.register_memory(
        memory_id="mem_002",
        source=MemorySource.INFERRED,
        base_confidence=0.6,
        extraction_method="context_inference",
        original_query=""
    )
    
    # 查看置信度
    print(f"mem_001 置信度: {tracker.get_confidence('mem_001'):.2f}")
    print(f"mem_002 置信度: {tracker.get_confidence('mem_002'):.2f}")
    
    # 验证记忆
    print("\n✅ 用户验证记忆...")
    tracker.verify("mem_001", verifier="user", notes="确认正确")
    tracker.verify("mem_001", verifier="user")
    
    print(f"mem_001 验证后置信度: {tracker.get_confidence('mem_001'):.2f}")
    
    # 质疑记忆
    print("\n❌ 质疑记忆...")
    tracker.contradict("mem_002", reason="用户否认")
    print(f"mem_002 质疑后置信度: {tracker.get_confidence('mem_002'):.2f}")
    
    # 详细报告
    print("\n📊 置信度报告 mem_001:")
    report = tracker.get_confidence_report("mem_001")
    for key, value in report.items():
        print(f"  {key}: {value}")
    
    print("✅ 置信度跟踪测试完成!")


path: conflict_resolver.py
content: """
Memory Conflict Resolution for Enhanced MemCore
记忆冲突解决器
处理新旧记忆之间的矛盾
"""

import json
from typing import List, Dict, Any, Optional, Tuple
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
import difflib


class ConflictStrategy(Enum):
    """冲突解决策略"""
    TIME_PRIORITY = "time"           # 新的覆盖旧的
    CONFIDENCE_PRIORITY = "confidence"  # 高置信度优先
    MERGE = "merge"                  # 合并如果可能
    KEEP_BOTH = "keep_both"          # 保留两者，标记冲突
    MANUAL_REVIEW = "manual"         # 交给用户确认


@dataclass
class MemoryConflict:
    """记忆冲突记录"""
    new_memory: Any
    existing_memory: Any
    conflict_type: str  # 'contradiction' | 'update' | 'duplicate'
    similarity_score: float  # 主题相似度
    suggested_action: str
    resolved: bool = False
    resolution: Optional[str] = None
    timestamp: datetime = field(default_factory=datetime.now)


class MemoryConflictResolver:
    """
    记忆冲突解决器
    
    使用场景：
    1. 新记忆与旧记忆矛盾
    2. 多源导入时的数据冲突
    3. 用户反馈导致的记忆修正
    """
    
    def __init__(
        self,
        default_strategy: ConflictStrategy = ConflictStrategy.CONFIDENCE_PRIORITY,
        similarity_threshold: float = 0.6
    ):
        self.default_strategy = default_strategy
        self.similarity_threshold = similarity_threshold  # 判断相似的阈值
        self.conflict_history: List[MemoryConflict] = []
    
    def detect_conflict(
        self,
        new_memory: Any,
        existing_memories: List[Any],
        check_fields: Optional[List[str]] = None
    ) -> List[MemoryConflict]:
        """
        检测潜在冲突
        
        Args:
            new_memory: 新记忆
            existing_memories: 已有记忆列表
            check_fields: 用于比较的字段
            
        Returns:
            冲突列表
        """
        conflicts = []
        
        for existing in existing_memories:
            # 计算主题相似度
            similarity = self._calculate_similarity(new_memory, existing, check_fields)
            
            if similarity >= self.similarity_threshold:
                # 检查是否矛盾
                is_contradiction, reason = self._is_contradictory(
                    new_memory, existing, check_fields
                )
                
                if is_contradiction:
                    conflict = MemoryConflict(
                        new_memory=new_memory,
                        existing_memory=existing,
                        conflict_type='contradiction',
                        similarity_score=similarity,
                        suggested_action=self._suggest_action(new_memory, existing)
                    )
                    conflicts.append(conflict)
                elif similarity > 0.9:
                    # 高度相似，可能是重复
                    conflict = MemoryConflict(
                        new_memory=new_memory,
                        existing_memory=existing,
                        conflict_type='duplicate',
                        similarity_score=similarity,
                        suggested_action='skip'
                    )
                    conflicts.append(conflict)
        
        return conflicts
    
    def resolve(
        self,
        new_memory: Any,
        conflicts: List[MemoryConflict],
        strategy: Optional[ConflictStrategy] = None
    ) -> Tuple[Any, List[MemoryConflict]]:
        """
        解决冲突
        
        Returns:
            (处理后的记忆, 更新后的冲突记录)
        """
        strategy = strategy or self.default_strategy
        
        if not conflicts:
            return new_memory, []
        
        # 按相似度排序，先处理最相似的
        conflicts.sort(key=lambda x: x.similarity_score, reverse=True)
        primary_conflict = conflicts[0]
        existing = primary_conflict.existing_memory
        
        if strategy == ConflictStrategy.TIME_PRIORITY:
            # 新的覆盖旧的
            new_memory = self._mark_outdated(existing)
            primary_conflict.resolved = True
            primary_conflict.resolution = "new_replaces_old"
            
        elif strategy == ConflictStrategy.CONFIDENCE_PRIORITY:
            # 比较置信度
            new_conf = getattr(new_memory, 'confidence', 1.0)
            old_conf = getattr(existing, 'confidence', 1.0)
            
            if new_conf >= old_conf:
                existing = self._mark_outdated(existing)
                primary_conflict.resolved = True
                primary_conflict.resolution = "higher_confidence_new"
            else:
                new_memory = self._mark_pending(new_memory)
                primary_conflict.resolved = True
                primary_conflict.resolution = "lower_confidence_pending"
                
        elif strategy == ConflictStrategy.MERGE:
            # 尝试合并
            merged = self._attempt_merge(new_memory, existing)
            if merged:
                new_memory = merged
                primary_conflict.resolved = True
                primary_conflict.resolution = "merged"
            else:
                # 合并失败，保留两者
                new_memory = self._mark_alternate(new_memory, existing)
                primary_conflict.resolved = True
                primary_conflict.resolution = "kept_both"
                
        elif strategy == ConflictStrategy.KEEP_BOTH:
            # 标记为不同版本
            new_memory = self._mark_alternate(new_memory, existing)
            primary_conflict.resolved = True
            primary_conflict.resolution = "kept_both"
            
        elif strategy == ConflictStrategy.MANUAL_REVIEW:
            # 标记为待确认
            new_memory = self._mark_pending(new_memory, conflicts)
            # 不标记为resolved，等待用户
        
        # 记录冲突历史
        self.conflict_history.extend(conflicts)
        
        return new_memory, conflicts
    
    def _calculate_similarity(
        self,
        mem1: Any,
        mem2: Any,
        check_fields: Optional[List[str]] = None
    ) -> float:
        """计算两条记忆的相似度"""
        
        # 如果有 key 字段，直接比较
        if hasattr(mem1, 'key') and hasattr(mem2, 'key'):
            if mem1.key == mem2.key:
                return 1.0
        
        # 如果有 context_summary，比较文本相似度
        text1 = self._get_comparable_text(mem1, check_fields)
        text2 = self._get_comparable_text(mem2, check_fields)
        
        return difflib.SequenceMatcher(None, text1, text2).ratio()
    
    def _get_comparable_text(self, memory: Any, fields: Optional[List[str]]) -> str:
        """获取可比较的文本"""
        if fields:
            parts = []
            for field in fields:
                val = getattr(memory, field, '')
                parts.append(str(val))
            return ' '.join(parts)
        
        # 默认字段
        for attr in ['content', 'context_summary', 'conclusion', 'value']:
            if hasattr(memory, attr):
                return str(getattr(memory, attr))
        
        return str(memory)
    
    def _is_contradictory(
        self,
        mem1: Any,
        mem2: Any,
        check_fields: Optional[List[str]] = None
    ) -> Tuple[bool, str]:
        """判断两条记忆是否矛盾"""
        
        # 如果是同一个 key 但 value 不同，则矛盾
        if hasattr(mem1, 'key') and hasattr(mem2, 'key'):
            if mem1.key == mem2.key:
                val1 = getattr(mem1, 'value', None) or getattr(mem1, 'content', None)
                val2 = getattr(mem2, 'value', None) or getattr(mem2, 'content', None)
                if val1 != val2:
                    return True, f"同一键 '{mem1.key}' 但值不同: {val1} vs {val2}"
        
        # 检查结论矛盾（针对情景记忆）
        if hasattr(mem1, 'conclusion') and hasattr(mem2, 'conclusion'):
            # 如果主题相似但结论完全不同，则可能矛盾
            topics1 = set(getattr(mem1, 'related_topics', []))
            topics2 = set(getattr(mem2, 'related_topics', []))
            
            if topics1 & topics2:  # 有共同主题
                # 简单的反义词检查
                concl1 = mem1.conclusion.lower()
                concl2 = mem2.conclusion.lower()
                
                antonyms = [
                    ('喜欢', '讨厌'),
                    ('赞同', '反对'),
                    ('是', '不是'),
                    ('true', 'false'),
                    ('yes', 'no'),
                    ('good', 'bad')
                ]
                
                for pos, neg in antonyms:
                    if (pos in concl1 and neg in concl2) or (neg in concl1 and pos in concl2):
                        return True, f"结论可能矛盾: {mem1.conclusion} vs {mem2.conclusion}"
        
        return False, ""
    
    def _suggest_action(self, new_mem: Any, existing_mem: Any) -> str:
        """根据特征建议处理方式"""
        new_conf = getattr(new_mem, 'confidence', 1.0)
        old_conf = getattr(existing_mem, 'confidence', 1.0)
        new_time = getattr(new_mem, 'timestamp', datetime.now())
        old_time = getattr(existing_mem, 'timestamp', datetime.now())
        
        if new_conf > old_conf:
            return "新记忆置信度更高，建议覆盖"
        elif new_time > old_time:
            return "新记忆更新，建议更新"
        else:
            return "存在冲突，需要确认"
    
    def _mark_outdated(self, memory: Any) -> Any:
        """标记记忆为过时"""
        if hasattr(memory, 'is_outdated'):
            memory.is_outdated = True
        if hasattr(memory, 'metadata'):
            memory.metadata['status'] = 'outdated'
        return memory
    
    def _mark_pending(self, memory: Any, conflicts: List[MemoryConflict] = None) -> Any:
        """标记记忆为待确认"""
        if hasattr(memory, 'status'):
            memory.status = 'pending_confirmation'
        if hasattr(memory, 'metadata'):
            memory.metadata['status'] = 'pending'
            if conflicts:
                memory.metadata['conflicts_with'] = [
                    c.existing_memory.id if hasattr(c.existing_memory, 'id') else str(c.existing_memory)
                    for c in conflicts
                ]
        return memory
    
    def _mark_alternate(self, new_memory: Any, existing_memory: Any) -> Any:
        """标记为备选版本"""
        if hasattr(new_memory, 'metadata'):
            new_memory.metadata['alternate_of'] = getattr(existing_memory, 'id', 'unknown')
            new_memory.metadata['version'] = 'alternate'
        return new_memory
    
    def _attempt_merge(self, mem1: Any, mem2: Any) -> Optional[Any]:
        """尝试合并两条记忆"""
        # 简单的合并策略：如果主题相同但结论互补，则合并
        if hasattr(mem1, 'related_topics') and hasattr(mem2, 'related_topics'):
            topics1 = set(mem1.related_topics)
            topics2 = set(mem2.related_topics)
            
            if topics1 == topics2:
                # 创建合并后的记忆
                if hasattr(mem1, 'conclusion') and hasattr(mem2, 'conclusion'):
                    merged_conclusion = f"{mem1.conclusion}; 另一观点: {mem2.conclusion}"
                    
                    # 创建新记忆（复制 mem1 并更新）
                    import copy
                    merged = copy.copy(mem1)
                    merged.conclusion = merged_conclusion
                    merged.metadata = getattr(mem1, 'metadata', {}).copy()
                    merged.metadata['merged_from'] = [
                        getattr(mem1, 'id', 'unknown'),
                        getattr(mem2, 'id', 'unknown')
                    ]
                    return merged
        
        return None
    
    def get_conflict_report(self) -> Dict[str, Any]:
        """获取冲突解决报告"""
        total = len(self.conflict_history)
        resolved = sum(1 for c in self.conflict_history if c.resolved)
        pending = total - resolved
        
        by_type = {}
        for c in self.conflict_history:
            by_type[c.conflict_type] = by_type.get(c.conflict_type, 0) + 1
        
        return {
            'total_conflicts': total,
            'resolved': resolved,
            'pending_review': pending,
            'by_type': by_type,
            'recent_conflicts': [
                {
                    'type': c.conflict_type,
                    'similarity': c.similarity_score,
                    'resolved': c.resolved,
                    'resolution': c.resolution
                }
                for c in self.conflict_history[-5:]
            ]
        }


# 测试代码
if __name__ == "__main__":
    print("🧠 测试 Conflict Resolver...")
    
    from dataclasses import dataclass as dc
    
    @dc
    class SimpleMemory:
        id: str
        key: str
        value: str
        confidence: float = 1.0
        timestamp: datetime = field(default_factory=datetime.now)
        is_outdated: bool = False
        status: str = "active"
        metadata: Dict = field(default_factory=dict)
    
    resolver = MemoryConflictResolver()
    
    # 测试数据
    old_mem = SimpleMemory(
        id="m1",
        key="favorite_language",
        value="Python",
        confidence=0.8
    )
    
    new_mem = SimpleMemory(
        id="m2",
        key="favorite_language",
        value="JavaScript",
        confidence=0.9
    )
    
    # 检测冲突
    conflicts = resolver.detect_conflict(new_mem, [old_mem], check_fields=['key'])
    print(f"检测到 {len(conflicts)} 个冲突")
    
    if conflicts:
        print(f"  冲突类型: {conflicts[0].conflict_type}")
        print(f"  相似度: {conflicts[0].similarity_score:.2f}")
        
        # 解决冲突
        resolved_mem, _ = resolver.resolve(new_mem, conflicts)
        print(f"  解决后状态: {getattr(resolved_mem, 'status', 'unknown')}")
    
    print("\n📊 冲突报告:", resolver.get_conflict_report())
    print("✅ 冲突解决测试完成!")


path: enhanced_memcore.py
content: """
Enhanced MemCore - 优化版五层记忆架构 + 四大增强模块
========================================================
在原 MemCore 基础上新增：
1. Episodic Memory（情景记忆）- 记录具体事件和结论
2. Semantic Compression（语义压缩）- 自动压缩冗余信息
3. Memory Triggers（记忆触发器）- 关键词触发的记忆加载
4. Forgetting Curve（遗忘曲线）- 模拟人类遗忘机制
"""

import json
import hashlib
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Any, Callable
from dataclasses import dataclass, field
from enum import Enum
import math


class MemoryPriority(Enum):
    """记忆优先级"""
    CRITICAL = 5    # 关键信息（如用户名字、重要偏好）
    HIGH = 4        # 重要信息
    MEDIUM = 3      # 一般信息
    LOW = 2         # 次要信息
    EPHEMERAL = 1   # 临时信息


@dataclass
class MemoryEntry:
    """记忆条目基类"""
    id: str
    content: Any
    timestamp: datetime
    priority: MemoryPriority
    access_count: int = 0
    last_accessed: datetime = field(default_factory=datetime.now)
    compression_level: int = 0  # 被压缩次数
    
    def touch(self):
        """访问时更新"""
        self.access_count += 1
        self.last_accessed = datetime.now()
    
    def get_forgetting_score(self, now: datetime = None) -> float:
        """
        计算遗忘分数 (0-1, 越高越应该被遗忘)
        基于艾宾浩斯遗忘曲线简化模型
        """
        if now is None:
            now = datetime.now()
        
        age_hours = (now - self.timestamp).total_seconds() / 3600
        last_access_hours = (now - self.last_accessed).total_seconds() / 3600
        
        # 基础遗忘曲线: R = e^(-t/S) 其中 S 是记忆强度
        # 优先级越高，记忆强度越大
        strength = self.priority.value * (1 + self.access_count * 0.1)
        base_retention = math.exp(-age_hours / (strength * 24))
        
        # 最近访问奖励
        recent_bonus = math.exp(-last_access_hours / 24) * 0.3
        
        # 压缩惩罚（被压缩过的记忆更容易遗忘）
        compression_penalty = self.compression_level * 0.1
        
        retention = base_retention + recent_bonus - compression_penalty
        return max(0, min(1, 1 - retention))  # 转换为遗忘分数


@dataclass
class EpisodicMemoryEntry:
    """
    情景记忆条目
    记录: "上次我们讨论X时，结论是Y"
    """
    # 基础字段
    id: str
    content: Any
    timestamp: datetime
    priority: MemoryPriority
    access_count: int = 0
    last_accessed: datetime = field(default_factory=datetime.now)
    compression_level: int = 0
    
    # 情景特有字段
    episode_type: str = "discussion"  # 如 "discussion", "decision", "event"
    participants: List[str] = field(default_factory=list)
    context_summary: str = ""  # 背景摘要
    conclusion: str = ""       # 结论/结果
    related_topics: List[str] = field(default_factory=list)
    
    def touch(self):
        """访问时更新"""
        self.access_count += 1
        self.last_accessed = datetime.now()
    
    def get_forgetting_score(self, now: datetime = None) -> float:
        """计算遗忘分数"""
        if now is None:
            now = datetime.now()
        
        age_hours = (now - self.timestamp).total_seconds() / 3600
        last_access_hours = (now - self.last_accessed).total_seconds() / 3600
        
        strength = self.priority.value * (1 + self.access_count * 0.1)
        base_retention = math.exp(-age_hours / (strength * 24))
        recent_bonus = math.exp(-last_access_hours / 24) * 0.3
        compression_penalty = self.compression_level * 0.1
        
        retention = base_retention + recent_bonus - compression_penalty
        return max(0, min(1, 1 - retention))
    
    def to_natural_language(self) -> str:
        """转换为自然语言描述"""
        time_str = self.timestamp.strftime("%Y-%m-%d %H:%M")
        return f"[{time_str}] {self.episode_type}: 关于 '{self.context_summary}' 的讨论，结论是：{self.conclusion}"


@dataclass
class MemoryTrigger:
    """记忆触发器"""
    id: str
    keywords: List[str]           # 触发关键词
    target_memory_ids: List[str]  # 要加载的记忆ID
    trigger_count: int = 0
    is_active: bool = True
    created_at: datetime = field(default_factory=datetime.now)
    
    def check_trigger(self, text: str) -> bool:
        """检查文本是否触发"""
        text_lower = text.lower()
        return any(kw.lower() in text_lower for kw in self.keywords)


class SemanticCompressor:
    """
    语义压缩器
    将多条消息/记忆压缩为一条摘要
    """
    
    def __init__(self, llm_compress_fn: Optional[Callable] = None):
        """
        Args:
            llm_compress_fn: 可选的 LLM 压缩函数
        """
        self.llm_compress_fn = llm_compress_fn
        self.compression_threshold = 5  # 多少条记录触发压缩
    
    def should_compress(self, entries: List[MemoryEntry]) -> bool:
        """判断是否需要压缩"""
        return len(entries) >= self.compression_threshold
    
    def compress_context_memory(self, messages: List[Dict]) -> Dict:
        """
        压缩上下文记忆
        将 N 条对话消息压缩为 1 条摘要
        """
        if len(messages) < self.compression_threshold:
            return None
        
        # 简单的规则压缩（实际可用 LLM）
        topics = self._extract_topics(messages)
        summary = f"[压缩记忆] 讨论了: {', '.join(topics)} (共{len(messages)}条消息)"
        
        return {
            "role": "system",
            "content": summary,
            "is_compressed": True,
            "original_count": len(messages),
            "compression_timestamp": datetime.now().isoformat()
        }
    
    def compress_episodic_memories(self, episodes: List[EpisodicMemoryEntry]) -> EpisodicMemoryEntry:
        """
        压缩多个情景记忆为一个
        """
        if not episodes:
            return None
        
        # 聚合相关主题
        all_topics = set()
        all_conclusions = []
        for ep in episodes:
            all_topics.update(ep.related_topics)
            all_conclusions.append(ep.conclusion)
        
        combined_conclusion = " | ".join(all_conclusions[:3])
        if len(all_conclusions) > 3:
            combined_conclusion += f" 等{len(all_conclusions)}个结论"
        
        compressed = EpisodicMemoryEntry(
            id=f"compressed_{hashlib.md5(str(datetime.now()).encode()).hexdigest()[:8]}",
            content=f"压缩了{len(episodes)}个相关情景",
            timestamp=datetime.now(),
            priority=max(ep.priority for ep in episodes),
            episode_type="compressed",
            context_summary=f"涉及主题: {', '.join(list(all_topics)[:5])}",
            conclusion=combined_conclusion,
            related_topics=list(all_topics)
        )
        compressed.compression_level = 1
        
        return compressed
    
    def _extract_topics(self, messages: List[Dict]) -> List[str]:
        """简单主题提取（可用 NLP 改进）"""
        # 这里简化处理，实际可用关键词提取
        return list(set([m.get("content", "")[:20] + "..." for m in messages[:3]]))


class ForgettingCurveManager:
    """
    遗忘曲线管理器
    模拟人类遗忘，定期清理低价值记忆
    """
    
    def __init__(
        self,
        forgetting_threshold: float = 0.8,  # 遗忘分数超过此值则清理
        check_interval_hours: int = 24
    ):
        self.forgetting_threshold = forgetting_threshold
        self.check_interval_hours = check_interval_hours
        self.last_check = datetime.now()
    
    def should_forget(self, entry: MemoryEntry) -> bool:
        """判断是否应该遗忘该记忆"""
        # 关键记忆永不忘却
        if entry.priority == MemoryPriority.CRITICAL:
            return False
        
        score = entry.get_forgetting_score()
        return score > self.forgetting_threshold
    
    def apply_forgetting(self, memory_store: Dict[str, MemoryEntry]) -> List[str]:
        """
        执行遗忘，返回被删除的记忆ID
        """
        now = datetime.now()
        
        # 检查间隔
        if (now - self.last_check).total_seconds() < self.check_interval_hours * 3600:
            return []
        
        self.last_check = now
        forgotten_ids = []
        
        for mem_id, entry in list(memory_store.items()):
            if self.should_forget(entry):
                del memory_store[mem_id]
                forgotten_ids.append(mem_id)
        
        return forgotten_ids
    
    def get_memory_stats(self, memory_store: Dict[str, MemoryEntry]) -> Dict:
        """获取记忆统计信息"""
        if not memory_store:
            return {}
        
        scores = [e.get_forgetting_score() for e in memory_store.values()]
        priorities = [e.priority.value for e in memory_store.values()]
        
        return {
            "total_memories": len(memory_store),
            "avg_forgetting_score": sum(scores) / len(scores),
            "high_risk_count": sum(1 for s in scores if s > self.forgetting_threshold),
            "avg_priority": sum(priorities) / len(priorities),
            "at_risk_ids": [
                mid for mid, e in memory_store.items()
                if e.get_forgetting_score() > self.forgetting_threshold
            ]
        }


class EnhancedMemoryRouter:
    """
    增强版记忆路由器
    整合新功能的中央控制器
    """
    
    def __init__(self, llm_compress_fn: Optional[Callable] = None):
        # 原有五层记忆
        self.context_memory: List[Dict] = []
        self.task_memory: Dict[str, Any] = {}
        self.user_memory: Dict[str, MemoryEntry] = {}
        self.knowledge_memory: Dict[str, Any] = {}
        self.experience_memory: Dict[str, Any] = {}
        
        # 新增四层
        self.episodic_memory: Dict[str, EpisodicMemoryEntry] = {}
        self.triggers: Dict[str, MemoryTrigger] = {}
        
        # 管理器
        self.compressor = SemanticCompressor(llm_compress_fn)
        self.forgetter = ForgettingCurveManager()
    
    # ========== 情景记忆接口 ==========
    
    def record_episode(
        self,
        episode_type: str,
        context_summary: str,
        conclusion: str,
        related_topics: List[str] = None,
        participants: List[str] = None,
        priority: MemoryPriority = MemoryPriority.MEDIUM
    ) -> str:
        """
        记录一个情景记忆
        
        示例:
            router.record_episode(
                episode_type="discussion",
                context_summary="用户询问 MemCore 优化建议",
                conclusion="建议添加 Episodic Memory 等四个模块",
                related_topics=["MemCore", "AI记忆", "架构设计"],
                priority=MemoryPriority.HIGH
            )
        """
        episode_id = f"ep_{hashlib.md5(str(datetime.now()).encode()).hexdigest()[:12]}"
        
        episode = EpisodicMemoryEntry(
            id=episode_id,
            content=f"{context_summary} -> {conclusion}",
            timestamp=datetime.now(),
            priority=priority,
            episode_type=episode_type,
            context_summary=context_summary,
            conclusion=conclusion,
            related_topics=related_topics or [],
            participants=participants or []
        )
        
        self.episodic_memory[episode_id] = episode
        
        # 自动创建记忆触发器
        self._auto_create_trigger(related_topics or [], [episode_id])
        
        return episode_id
    
    def recall_episodes(
        self,
        topic: str = None,
        episode_type: str = None,
        limit: int = 5
    ) -> List[EpisodicMemoryEntry]:
        """回忆相关情景"""
        results = []
        
        for episode in self.episodic_memory.values():
            match = True
            if topic and topic not in episode.related_topics:
                match = False
            if episode_type and episode.episode_type != episode_type:
                match = False
            
            if match:
                episode.touch()  # 访问即强化记忆
                results.append(episode)
        
        # 按优先级和时间排序
        results.sort(key=lambda e: (e.priority.value, e.timestamp), reverse=True)
        return results[:limit]
    
    # ========== 记忆触发器接口 ==========
    
    def create_trigger(
        self,
        keywords: List[str],
        target_memory_ids: List[str],
        trigger_id: str = None
    ) -> str:
        """
        创建记忆触发器
        
        示例:
            router.create_trigger(
                keywords=["项目X", "Project X"],
                target_memory_ids=["ep_abc123", "user_pref_456"]
            )
        """
        tid = trigger_id or f"tr_{hashlib.md5(str(datetime.now()).encode()).hexdigest()[:8]}"
        
        trigger = MemoryTrigger(
            id=tid,
            keywords=keywords,
            target_memory_ids=target_memory_ids
        )
        
        self.triggers[tid] = trigger
        return tid
    
    def process_input(self, text: str) -> Dict[str, Any]:
        """
        处理用户输入，检查触发器并加载相关记忆
        
        Returns:
            {
                "triggered": bool,
                "loaded_memories": [...],
                "suggested_context": str
            }
        """
        result = {
            "triggered": False,
            "loaded_memories": [],
            "suggested_context": ""
        }
        
        for trigger in self.triggers.values():
            if not trigger.is_active:
                continue
            
            if trigger.check_trigger(text):
                trigger.trigger_count += 1
                result["triggered"] = True
                
                # 加载相关记忆
                for mem_id in trigger.target_memory_ids:
                    if mem_id in self.episodic_memory:
                        episode = self.episodic_memory[mem_id]
                        episode.touch()
                        result["loaded_memories"].append(episode.to_natural_language())
                    elif mem_id in self.user_memory:
                        entry = self.user_memory[mem_id]
                        entry.touch()
                        result["loaded_memories"].append(f"[用户偏好] {entry.content}")
        
        if result["loaded_memories"]:
            result["suggested_context"] = "\n".join(result["loaded_memories"])
        
        return result
    
    def _auto_create_trigger(self, topics: List[str], memory_ids: List[str]):
        """自动为新主题创建触发器"""
        for topic in topics:
            # 检查是否已有该主题的触发器
            exists = any(
                topic in t.keywords for t in self.triggers.values()
            )
            if not exists:
                self.create_trigger([topic], memory_ids)
    
    # ========== 语义压缩接口 ==========
    
    def compress_memories(self, memory_type: str = "context") -> Optional[Any]:
        """
        执行语义压缩
        
        Args:
            memory_type: "context" | "episodic"
        """
        if memory_type == "context":
            if self.compressor.should_compress([
                MemoryEntry(id=str(i), content=m, timestamp=datetime.now(), priority=MemoryPriority.LOW)
                for i, m in enumerate(self.context_memory)
            ]):
                compressed = self.compressor.compress_context_memory(self.context_memory)
                if compressed:
                    # 保留最近的2条，其余替换为压缩版本
                    self.context_memory = self.context_memory[-2:] + [compressed]
                    return compressed
        
        elif memory_type == "episodic":
            # 压缩相似的情景记忆
            episodes = list(self.episodic_memory.values())
            if len(episodes) >= 10:
                # 按主题分组压缩
                by_topic = {}
                for ep in episodes:
                    for topic in ep.related_topics:
                        by_topic.setdefault(topic, []).append(ep)
                
                for topic, eps in by_topic.items():
                    if len(eps) >= 5:
                        compressed = self.compressor.compress_episodic_memories(eps)
                        # 删除原记忆，添加压缩版
                        for ep in eps:
                            del self.episodic_memory[ep.id]
                        self.episodic_memory[compressed.id] = compressed
        
        return None
    
    # ========== 遗忘曲线接口 ==========
    
    def run_forgetting_cycle(self) -> Dict:
        """
        运行遗忘周期
        
        Returns:
            统计信息
        """
        stats_before = self.forgetter.get_memory_stats(self.episodic_memory)
        
        # 执行遗忘
        forgotten = self.forgetter.apply_forgetting(self.episodic_memory)
        
        stats_after = self.forgetter.get_memory_stats(self.episodic_memory)
        
        return {
            "forgotten_ids": forgotten,
            "forgotten_count": len(forgotten),
            "stats_before": stats_before,
            "stats_after": stats_after
        }
    
    def get_memory_health(self) -> Dict:
        """获取记忆健康报告"""
        return {
            "episodic_memory": self.forgetter.get_memory_stats(self.episodic_memory),
            "trigger_count": len(self.triggers),
            "context_size": len(self.context_memory),
            "total_stored": len(self.episodic_memory) + len(self.user_memory)
        }
    
    # ========== 原有接口（保持兼容） ==========
    
    def add_to_context(self, message: Dict):
        """添加上下文消息"""
        self.context_memory.append(message)
        
        # 自动压缩检查
        if len(self.context_memory) > 20:
            self.compress_memories("context")
    
    def update_user_memory(self, key: str, value: Any, priority: MemoryPriority = MemoryPriority.MEDIUM):
        """更新用户记忆"""
        entry = MemoryEntry(
            id=f"user_{key}",
            content=value,
            timestamp=datetime.now(),
            priority=priority
        )
        self.user_memory[key] = entry


# ========== 使用示例 ==========

def demo():
    """演示增强版 MemCore 的使用"""
    
    print("=" * 60)
    print("🧠 Enhanced MemCore Demo")
    print("=" * 60)
    
    # 初始化
    router = EnhancedMemoryRouter()
    
    # 1. 记录情景记忆
    print("\n📌 记录情景记忆...")
    ep1 = router.record_episode(
        episode_type="discussion",
        context_summary="用户询问 MemCore 优化建议",
        conclusion="建议添加 Episodic Memory 等四个模块",
        related_topics=["MemCore", "AI记忆", "架构设计"],
        priority=MemoryPriority.HIGH
    )
    print(f"   记录情景: {ep1}")
    
    ep2 = router.record_episode(
        episode_type="decision",
        context_summary="确定使用 MIT-0 许可证",
        conclusion="MemCore 采用 MIT-0 开源许可证",
        related_topics=["MemCore", "开源", "许可证"],
        priority=MemoryPriority.MEDIUM
    )
    print(f"   记录情景: {ep2}")
    
    # 2. 自动触发器工作
    print("\n🎯 测试记忆触发器...")
    result = router.process_input("我想了解一下 MemCore 的架构")
    if result["triggered"]:
        print("   ✓ 触发成功！")
        print(f"   加载记忆:\n   {result['suggested_context']}")
    
    # 3. 回忆功能
    print("\n🔍 回忆关于 'MemCore' 的情景...")
    episodes = router.recall_episodes(topic="MemCore")
    for ep in episodes:
        print(f"   - {ep.to_natural_language()}")
    
    # 4. 模拟时间流逝，测试遗忘
    print("\n⏰ 模拟遗忘周期...")
    # 添加一些低优先级临时记忆
    for i in range(5):
        router.record_episode(
            episode_type="temp",
            context_summary=f"临时测试记忆 {i}",
            conclusion=f"测试结论 {i}",
            related_topics=["test"],
            priority=MemoryPriority.EPHEMERAL
        )
    
    # 手动设置旧时间戳来模拟
    for ep in router.episodic_memory.values():
        if ep.episode_type == "temp":
            ep.timestamp = datetime.now() - timedelta(days=30)
            ep.last_accessed = datetime.now() - timedelta(days=30)
    
    health_before = router.get_memory_health()
    print(f"   遗忘前: {health_before['episodic_memory']['total_memories']} 条记忆")
    
    result = router.run_forgetting_cycle()
    print(f"   遗忘后: 清理了 {result['forgotten_count']} 条记忆")
    
    # 5. 健康报告
    print("\n📊 记忆健康报告:")
    health = router.get_memory_health()
    print(f"   - 情景记忆: {health['episodic_memory']['total_memories']} 条")
    print(f"   - 触发器: {health['trigger_count']} 个")
    print(f"   - 平均遗忘风险: {health['episodic_memory'].get('avg_forgetting_score', 0):.2f}")
    
    print("\n" + "=" * 60)
    print("✅ Demo 完成!")
    print("=" * 60)


if __name__ == "__main__":
    demo()


path: memcore_enhanced.py
content: """
Enhanced MemCore - 完整增强版
=====================================
原版 MemCore + 四大新功能：
1. Episodic Memory（情景记忆）
2. Semantic Compression（语义压缩）
3. Memory Triggers（记忆触发器）
4. Forgetting Curve（遗忘曲线）

额外增强：
5. Persistent Storage（持久化存储）
6. Vector Knowledge（向量检索）
7. Conflict Resolution（冲突解决）
8. Confidence Tracking（置信度跟踪）
"""

from typing import Dict, List, Any, Optional, Union, Callable
from datetime import datetime, timedelta
import hashlib
import json

# 导入各模块
from enhanced_memcore import (
    EpisodicMemoryEntry, MemoryTrigger, SemanticCompressor,
    ForgettingCurveManager, MemoryPriority
)
from persistent_backend import SQLiteBackend, JSONBackend
from vector_knowledge import VectorKnowledgeMemory
from conflict_resolver import MemoryConflictResolver, ConflictStrategy
from confidence_tracker import ConfidenceTracker, MemorySource


class MemCoreEnhanced:
    """
    增强版 MemCore 记忆系统
    
    使用示例：
        memcore = MemCoreEnhanced()
        
        # 记录情景
        memcore.record_episode(
            context_summary="用户询问 MemCore",
            conclusion="用户是开发者",
            related_topics=["MemCore"]
        )
        
        # 查询时触发记忆
        result = memcore.process_input("我想继续弄记忆系统")
    """
    
    def __init__(
        self,
        db_path: str = "~/.memcore/memory.db",
        embedding_fn: Optional[Callable] = None,
        enable_persistence: bool = True
    ):
        """
        初始化增强版 MemCore
        
        Args:
            db_path: SQLite 数据库路径
            embedding_fn: 向量嵌入函数（可选）
            enable_persistence: 是否启用持久化
        """
        print("🚀 初始化 Enhanced MemCore...")
        
        # 持久化后端
        self.backend = SQLiteBackend(db_path) if enable_persistence else None
        
        # 核心记忆存储
        self.episodic_memory: Dict[str, EpisodicMemoryEntry] = {}
        self.triggers: Dict[str, MemoryTrigger] = {}
        self.context_memory: List[Dict] = []
        
        # 增强模块
        self.compressor = SemanticCompressor()
        self.forgetter = ForgettingCurveManager()
        self.conflict_resolver = MemoryConflictResolver()
        self.confidence_tracker = ConfidenceTracker()
        
        # 向量知识库
        self.knowledge = VectorKnowledgeMemory(
            embedding_fn=embedding_fn,
            backend=self.backend
        )
        
        # 加载已存储的记忆
        if enable_persistence:
            self._load_from_storage()
        
        print("\u2705 Enhanced MemCore 就绪!")
    
    def _load_from_storage(self):
        """从持久化存储加载记忆"""
        if not self.backend:
            return
        
        # 加载情景记忆
        episodes_data = self.backend.load_episodic_memories(limit=1000)
        for data in episodes_data:
            episode = EpisodicMemoryEntry(
                id=data['id'],
                content=data['content'],
                timestamp=data['timestamp'],
                priority=MemoryPriority(data['priority']),
                access_count=data['access_count'],
                last_accessed=data['last_accessed'],
                compression_level=data['compression_level'],
                episode_type=data['episode_type'],
                context_summary=data['context_summary'],
                conclusion=data['conclusion'],
                related_topics=data['related_topics'],
                participants=data['participants']
            )
            self.episodic_memory[episode.id] = episode
        
        # 加载触发器
        triggers_data = self.backend.load_triggers()
        for data in triggers_data:
            trigger = MemoryTrigger(
                id=data['id'],
                keywords=data['keywords'],
                target_memory_ids=data['target_memory_ids'],
                trigger_count=data['trigger_count']
            )
            self.triggers[trigger.id] = trigger
        
        print(f"   📂 加载了 {len(self.episodic_memory)} 条情景记忆")
        print(f"   🔔 加载了 {len(self.triggers)} 个触发器")
    
    # ========== 情景记忆接口 ==========
    
    def record_episode(
        self,
        context_summary: str,
        conclusion: str,
        episode_type: str = "discussion",
        related_topics: List[str] = None,
        participants: List[str] = None,
        priority: MemoryPriority = MemoryPriority.MEDIUM,
        confidence: float = 1.0,
        source: MemorySource = MemorySource.EXPLICIT
    ) -> str:
        """
        记录情景记忆
        
        Returns:
            情景ID
        """
        episode_id = f"ep_{hashlib.md5(str(datetime.now()).encode()).hexdigest()[:12]}"
        
        episode = EpisodicMemoryEntry(
            id=episode_id,
            content=f"{context_summary} -> {conclusion}",
            timestamp=datetime.now(),
            priority=priority,
            episode_type=episode_type,
            context_summary=context_summary,
            conclusion=conclusion,
            related_topics=related_topics or [],
            participants=participants or []
        )
        
        # 检查冲突
        conflicts = self.conflict_resolver.detect_conflict(
            episode, list(self.episodic_memory.values())
        )
        
        if conflicts:
            episode, _ = self.conflict_resolver.resolve(episode, conflicts)
        
        # 保存到内存
        self.episodic_memory[episode_id] = episode
        
        # 注册置信度
        self.confidence_tracker.register_memory(
            episode_id, source, confidence,
            extraction_method="record_episode"
        )
        
        # 持久化
        if self.backend:
            self.backend.save_episodic_memory(episode)
        
        # 自动创建触发器
        self._auto_create_trigger(related_topics or [], [episode_id])
        
        return episode_id
    
    def recall_episodes(
        self,
        topic: Optional[str] = None,
        episode_type: Optional[str] = None,
        min_confidence: float = 0.0,
        limit: int = 5
    ) -> List[EpisodicMemoryEntry]:
        """
        回忆情景
        
        Args:
            min_confidence: 最低置信度筛选
        """
        results = []
        
        for episode in self.episodic_memory.values():
            # 检查置信度
            conf = self.confidence_tracker.get_confidence(episode.id)
            if conf < min_confidence:
                continue
            
            # 检查过滤条件
            if topic and topic not in episode.related_topics:
                continue
            if episode_type and episode.episode_type != episode_type:
                continue
            
            episode.touch()
            results.append(episode)
            
            # 更新访问时间
            if self.backend:
                self.backend.update_episode_access(episode.id)
        
        # 按优先级和置信度排序
        results.sort(
            key=lambda e: (
                e.priority.value,
                self.confidence_tracker.get_confidence(e.id),
                e.timestamp
            ),
            reverse=True
        )
        
        return results[:limit]
    
    # ========== 记忆触发器 ==========
    
    def create_trigger(
        self,
        keywords: List[str],
        target_memory_ids: List[str],
        trigger_id: Optional[str] = None
    ) -> str:
        """创建记忆触发器"""
        tid = trigger_id or f"tr_{hashlib.md5(str(datetime.now()).encode()).hexdigest()[:8]}"
        
        trigger = MemoryTrigger(
            id=tid,
            keywords=keywords,
            target_memory_ids=target_memory_ids
        )
        
        self.triggers[tid] = trigger
        
        if self.backend:
            self.backend.save_trigger(trigger)
        
        return tid
    
    def process_input(self, text: str) -> Dict[str, Any]:
        """
        处理用户输入，触发相关记忆
        
        Returns:
            {
                "triggered": bool,
                "loaded_memories": [...],
                "suggested_context": str,
                "related_knowledge": [...]
            }
        """
        result = {
            "triggered": False,
            "loaded_memories": [],
            "suggested_context": "",
            "related_knowledge": []
        }
        
        # 检查触发器
        for trigger in self.triggers.values():
            if not trigger.is_active:
                continue
            
            if trigger.check_trigger(text):
                trigger.trigger_count += 1
                result["triggered"] = True
                
                if self.backend:
                    self.backend.increment_trigger_count(trigger.id)
                
                # 加载记忆
                for mem_id in trigger.target_memory_ids:
                    if mem_id in self.episodic_memory:
                        episode = self.episodic_memory[mem_id]
                        episode.touch()
                        
                        # 检查置信度
                        conf = self.confidence_tracker.get_confidence(mem_id)
                        if conf >= 0.5:  # 只显示置信度足够的记忆
                            result["loaded_memories"].append({
                                "type": "episodic",
                                "content": episode.to_natural_language(),
                                "confidence": conf
                            })
        
        # 检索相关知识
        knowledge_results = self.knowledge.query(text, top_k=3)
        for doc, score in knowledge_results:
            result["related_knowledge"].append({
                "content": doc.content,
                "similarity": score,
                "source": doc.source
            })
        
        # 组装上下文
        context_parts = []
        for mem in result["loaded_memories"]:
            if mem["confidence"] >= 0.7:
                context_parts.append(f"[记忆] {mem['content']}")
            else:
                context_parts.append(f"[可能相关] {mem['content']} (置信度: {mem['confidence']:.2f})")
        
        for know in result["related_knowledge"]:
            context_parts.append(f"[知识] {know['content'][:100]}...")
        
        result["suggested_context"] = "\n".join(context_parts)
        
        return result
    
    def _auto_create_trigger(self, topics: List[str], memory_ids: List[str]):
        """自动创建触发器"""
        for topic in topics:
            exists = any(topic in t.keywords for t in self.triggers.values())
            if not exists:
                self.create_trigger([topic], memory_ids)
    
    # ========== 遗忘管理 ==========
    
    def run_forgetting_cycle(self) -> Dict[str, Any]:
        """运行遗忘周期"""
        if not self.backend:
            return {"error": "Persistence not enabled"}
        
        # 获取高风险记忆
        at_risk_ids = self.backend.get_high_forgetting_risk_memories(threshold=0.8)
        
        deleted = []
        for mem_id in at_risk_ids:
            # 检查不是 CRITICAL 优先级
            if mem_id in self.episodic_memory:
                episode = self.episodic_memory[mem_id]
                if episode.priority != MemoryPriority.CRITICAL:
                    # 删除
                    self.backend.delete_episodic_memory(mem_id)
                    del self.episodic_memory[mem_id]
                    deleted.append(mem_id)
        
        return {
            "checked": len(at_risk_ids),
            "deleted": len(deleted),
            "deleted_ids": deleted
        }
    
    # ========== 知识管理 ==========
    
    def add_knowledge(
        self,
        content: str,
        metadata: Optional[Dict] = None,
        source: str = ""
    ) -> str:
        """添加知识"""
        return self.knowledge.add_knowledge(content, metadata, source)
    
    def query_knowledge(self, query: str, top_k: int = 3) -> List[Dict]:
        """查询知识"""
        results = self.knowledge.query(query, top_k=top_k)
        return [
            {
                "content": doc.content,
                "similarity": score,
                "metadata": doc.metadata
            }
            for doc, score in results
        ]
    
    # ========== 用户偏好 ==========
    
    def update_user_preference(
        self,
        user_id: str,
        key: str,
        value: Any,
        confidence: float = 1.0,
        source: MemorySource = MemorySource.EXPLICIT
    ):
        """更新用户偏好"""
        if self.backend:
            self.backend.save_user_memory(
                user_id, key, value,
                confidence=confidence,
                source=source.value
            )
        
        # 注册置信度
        mem_id = f"{user_id}_{key}"
        self.confidence_tracker.register_memory(
            mem_id, source, confidence
        )
    
    # ========== 统计和报告 ==========
    
    def get_health_report(self) -> Dict[str, Any]:
        """获取系统健康报告"""
        report = {
            "episodic_memory": {
                "count": len(self.episodic_memory),
                "by_priority": self._count_by_priority()
            },
            "triggers": {
                "count": len(self.triggers),
                "total_triggered": sum(t.trigger_count for t in self.triggers.values())
            },
            "knowledge": self.knowledge.get_stats(),
            "confidence": {
                "low_confidence_memories": len(
                    self.confidence_tracker.get_low_confidence_memories(0.5)
                )
            }
        }
        
        if self.backend:
            db_stats = self.backend.get_memory_stats()
            report["database"] = db_stats
        
        return report
    
    def _count_by_priority(self) -> Dict[str, int]:
        """按优先级统计"""
        counts = {}
        for p in MemoryPriority:
            counts[p.name] = sum(
                1 for e in self.episodic_memory.values()
                if e.priority == p
            )
        return counts


# 完整演示
if __name__ == "__main__":
    print("🧠 Enhanced MemCore 完整演示")
    print("=" * 60)
    
    # 初始化
    mc = MemCoreEnhanced(enable_persistence=False)
    
    # 1. 记录情景
    print("\n📌 记录情景记忆...")
    ep1 = mc.record_episode(
        context_summary="用户询问 MemCore 优化",
        conclusion="用户是 MemCore 开发者，想要四个新功能",
        related_topics=["MemCore", "AI记忆"],
        priority=MemoryPriority.HIGH,
        confidence=1.0
    )
    print(f"   记录情景: {ep1}")
    
    # 2. 添加知识
    print("\n📚 添加知识...")
    mc.add_knowledge(
        content="MemCore 采用五层记忆架构: Context/Task/User/Knowledge/Experience",
        metadata={"topics": ["MemCore", "architecture"]},
        source="docs"
    )
    
    # 3. 触发器测试
    print("\n🎯 测试触发器...")
    result = mc.process_input("我想继续搞 MemCore 的优化")
    print(f"   触发结果: {result['triggered']}")
    print(f"   加载记忆: {len(result['loaded_memories'])}")
    print(f"   相关知识: {len(result['related_knowledge'])}")
    
    if result['suggested_context']:
        print(f"   建议上下文:\n   {result['suggested_context'][:200]}...")
    
    # 4. 置信度验证
    print("\n✅ 验证记忆...")
    mc.confidence_tracker.verify(ep1, verifier="user")
    print(f"   验证后置信度: {mc.confidence_tracker.get_confidence(ep1):.2f}")
    
    # 5. 健康报告
    print("\n📊 系统健康报告:")
    health = mc.get_health_report()
    print(json.dumps(health, indent=2, default=str))
    
    print("\n" + "=" * 60)
    print("✅ 演示完成! Enhanced MemCore 可正常工作~")


path: persistent_backend.py
content: """
Persistent Backend for Enhanced MemCore
增强版 MemCore 的持久化存储后端
支持 SQLite 和 JSON 文件两种模式
"""

import sqlite3
import json
import os
from datetime import datetime
from typing import Dict, List, Optional, Any, Union
from dataclasses import asdict
from contextlib import contextmanager
import threading


class SQLiteBackend:
    """
    SQLite 持久化后端
    支持:
    - 情景记忆存储
    - 用户记忆存储
    - 触发器存储
    - 遗忘分数索引
    - 语义检索
    """
    
    def __init__(self, db_path: str = "~/.memcore/memory.db"):
        self.db_path = os.path.expanduser(db_path)
        os.makedirs(os.path.dirname(self.db_path), exist_ok=True)
        
        # 线程安全的连接池
        self._local = threading.local()
        self._init_database()
    
    @property
    def conn(self):
        """获取线程本地连接"""
        if not hasattr(self._local, 'conn') or self._local.conn is None:
            self._local.conn = sqlite3.connect(self.db_path, check_same_thread=False)
            self._local.conn.row_factory = sqlite3.Row
        return self._local.conn
    
    def _init_database(self):
        """初始化数据库表结构"""
        cursor = self.conn.cursor()
        
        # 情景记忆表
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS episodic_memory (
                id TEXT PRIMARY KEY,
                episode_type TEXT NOT NULL,
                context_summary TEXT NOT NULL,
                conclusion TEXT NOT NULL,
                content TEXT NOT NULL,
                related_topics TEXT,  -- JSON 数组
                participants TEXT,    -- JSON 数组
                priority INTEGER DEFAULT 3,
                access_count INTEGER DEFAULT 0,
                compression_level INTEGER DEFAULT 0,
                forgetting_score REAL DEFAULT 0.0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                last_accessed TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        
        # 用户记忆表
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS user_memory (
                id TEXT PRIMARY KEY,
                user_id TEXT NOT NULL,
                key TEXT NOT NULL,
                value TEXT NOT NULL,
                value_type TEXT DEFAULT 'str',
                priority INTEGER DEFAULT 3,
                confidence REAL DEFAULT 1.0,
                source TEXT DEFAULT 'explicit',
                verification_count INTEGER DEFAULT 0,
                is_outdated BOOLEAN DEFAULT 0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                last_accessed TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(user_id, key)
            )
        """)
        
        # 触发器表
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS memory_triggers (
                id TEXT PRIMARY KEY,
                keywords TEXT NOT NULL,  -- JSON 数组
                target_memory_ids TEXT NOT NULL,  -- JSON 数组
                trigger_count INTEGER DEFAULT 0,
                is_active BOOLEAN DEFAULT 1,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        
        # 任务记忆表
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS task_memory (
                id TEXT PRIMARY KEY,
                user_id TEXT NOT NULL,
                goal TEXT NOT NULL,
                task_type TEXT NOT NULL,
                status TEXT DEFAULT 'pending',
                steps TEXT,  -- JSON 数组
                current_step INTEGER DEFAULT 0,
                results TEXT,  -- JSON 对象
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        
        # 知识库表（支持向量检索）
        cursor.execute("""
            CREATE TABLE IF NOT EXISTS knowledge_memory (
                id TEXT PRIMARY KEY,
                content TEXT NOT NULL,
                embedding BLOB,  -- 向量嵌入
                metadata TEXT,   -- JSON 对象
                source TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        """)
        
        # 创建索引优化查询
        cursor.execute("""
            CREATE INDEX IF NOT EXISTS idx_episodic_topics 
            ON episodic_memory(related_topics)
        """)
        cursor.execute("""
            CREATE INDEX IF NOT EXISTS idx_episodic_forgetting 
            ON episodic_memory(forgetting_score, priority)
        """)
        cursor.execute("""
            CREATE INDEX IF NOT EXISTS idx_user_memory 
            ON user_memory(user_id, key)
        """)
        cursor.execute("""
            CREATE INDEX IF NOT EXISTS idx_task_user 
            ON task_memory(user_id, status)
        """)
        
        self.conn.commit()
        print(f"💾 数据库初始化完成: {self.db_path}")
    
    # ========== 情景记忆 CRUD ==========
    
    def save_episodic_memory(self, episode: 'EpisodicMemoryEntry') -> bool:
        """保存/更新情景记忆"""
        cursor = self.conn.cursor()
        
        cursor.execute("""
            INSERT OR REPLACE INTO episodic_memory (
                id, episode_type, context_summary, conclusion, content,
                related_topics, participants, priority, access_count,
                compression_level, forgetting_score, created_at, last_accessed
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        """, (
            episode.id,
            episode.episode_type,
            episode.context_summary,
            episode.conclusion,
            json.dumps(episode.content, ensure_ascii=False),
            json.dumps(episode.related_topics, ensure_ascii=False),
            json.dumps(episode.participants, ensure_ascii=False),
            episode.priority.value if hasattr(episode.priority, 'value') else episode.priority,
            episode.access_count,
            episode.compression_level,
            episode.get_forgetting_score(),
            episode.timestamp.isoformat(),
            episode.last_accessed.isoformat()
        ))
        
        self.conn.commit()
        return True
    
    def load_episodic_memories(
        self,
        topic: Optional[str] = None,
        episode_type: Optional[str] = None,
        limit: int = 100
    ) -> List[Dict]:
        """加载情景记忆"""
        cursor = self.conn.cursor()
        
        query = "SELECT * FROM episodic_memory WHERE 1=1"
        params = []
        
        if topic:
            query += " AND related_topics LIKE ?"
            params.append(f'%"{topic}"%')
        
        if episode_type:
            query += " AND episode_type = ?"
            params.append(episode_type)
        
        query += " ORDER BY priority DESC, last_accessed DESC LIMIT ?"
        params.append(limit)
        
        cursor.execute(query, params)
        rows = cursor.fetchall()
        
        return [self._row_to_episode_dict(row) for row in rows]
    
    def _row_to_episode_dict(self, row: sqlite3.Row) -> Dict:
        """将数据库行转换为字典"""
        return {
            'id': row['id'],
            'episode_type': row['episode_type'],
            'context_summary': row['context_summary'],
            'conclusion': row['conclusion'],
            'content': json.loads(row['content']),
            'related_topics': json.loads(row['related_topics']) if row['related_topics'] else [],
            'participants': json.loads(row['participants']) if row['participants'] else [],
            'priority': row['priority'],
            'access_count': row['access_count'],
            'compression_level': row['compression_level'],
            'timestamp': datetime.fromisoformat(row['created_at']),
            'last_accessed': datetime.fromisoformat(row['last_accessed'])
        }
    
    def update_episode_access(self, episode_id: str):
        """更新记忆访问时间"""
        cursor = self.conn.cursor()
        cursor.execute("""
            UPDATE episodic_memory 
            SET access_count = access_count + 1, 
                last_accessed = CURRENT_TIMESTAMP 
            WHERE id = ?
        """, (episode_id,))
        self.conn.commit()
    
    def delete_episodic_memory(self, episode_id: str) -> bool:
        """删除情景记忆"""
        cursor = self.conn.cursor()
        cursor.execute("DELETE FROM episodic_memory WHERE id = ?", (episode_id,))
        self.conn.commit()
        return cursor.rowcount > 0
    
    def get_high_forgetting_risk_memories(self, threshold: float = 0.8) -> List[str]:
        """获取高遗忘风险的记忆ID"""
        cursor = self.conn.cursor()
        cursor.execute("""
            SELECT id FROM episodic_memory 
            WHERE forgetting_score > ? AND priority < 5
        """, (threshold,))
        return [row['id'] for row in cursor.fetchall()]
    
    # ========== 用户记忆 CRUD ==========
    
    def save_user_memory(self, user_id: str, key: str, value: Any, **metadata) -> bool:
        """保存用户记忆"""
        cursor = self.conn.cursor()
        
        cursor.execute("""
            INSERT OR REPLACE INTO user_memory (
                id, user_id, key, value, value_type, priority,
                confidence, source, verification_count, is_outdated,
                last_accessed
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
        """, (
            f"{user_id}_{key}",
            user_id,
            key,
            json.dumps(value, ensure_ascii=False),
            metadata.get('value_type', type(value).__name__),
            metadata.get('priority', 3),
            metadata.get('confidence', 1.0),
            metadata.get('source', 'explicit'),
            metadata.get('verification_count', 0),
            metadata.get('is_outdated', False)
        ))
        
        self.conn.commit()
        return True
    
    def load_user_memory(self, user_id: str, key: Optional[str] = None) -> Union[Dict, List[Dict]]:
        """加载用户记忆"""
        cursor = self.conn.cursor()
        
        if key:
            cursor.execute("""
                SELECT * FROM user_memory WHERE user_id = ? AND key = ? AND is_outdated = 0
            """, (user_id, key))
            row = cursor.fetchone()
            return self._row_to_user_dict(row) if row else None
        else:
            cursor.execute("""
                SELECT * FROM user_memory WHERE user_id = ? AND is_outdated = 0
                ORDER BY priority DESC, last_accessed DESC
            """, (user_id,))
            return [self._row_to_user_dict(row) for row in cursor.fetchall()]
    
    def _row_to_user_dict(self, row: sqlite3.Row) -> Dict:
        """转换用户记忆行"""
        return {
            'id': row['id'],
            'user_id': row['user_id'],
            'key': row['key'],
            'value': json.loads(row['value']),
            'priority': row['priority'],
            'confidence': row['confidence'],
            'source': row['source'],
            'verification_count': row['verification_count'],
            'created_at': row['created_at'],
            'last_accessed': row['last_accessed']
        }
    
    # ========== 触发器 CRUD ==========
    
    def save_trigger(self, trigger: 'MemoryTrigger') -> bool:
        """保存触发器"""
        cursor = self.conn.cursor()
        
        cursor.execute("""
            INSERT OR REPLACE INTO memory_triggers (
                id, keywords, target_memory_ids, trigger_count, is_active
            ) VALUES (?, ?, ?, ?, ?)
        """, (
            trigger.id,
            json.dumps(trigger.keywords, ensure_ascii=False),
            json.dumps(trigger.target_memory_ids, ensure_ascii=False),
            trigger.trigger_count,
            trigger.is_active
        ))
        
        self.conn.commit()
        return True
    
    def load_triggers(self) -> List[Dict]:
        """加载所有活跃触发器"""
        cursor = self.conn.cursor()
        cursor.execute("""
            SELECT * FROM memory_triggers WHERE is_active = 1
        """)
        
        triggers = []
        for row in cursor.fetchall():
            triggers.append({
                'id': row['id'],
                'keywords': json.loads(row['keywords']),
                'target_memory_ids': json.loads(row['target_memory_ids']),
                'trigger_count': row['trigger_count']
            })
        return triggers
    
    def increment_trigger_count(self, trigger_id: str):
        """增加触发器计数"""
        cursor = self.conn.cursor()
        cursor.execute("""
            UPDATE memory_triggers 
            SET trigger_count = trigger_count + 1 
            WHERE id = ?
        """, (trigger_id,))
        self.conn.commit()
    
    # ========== 统计和维护 ==========
    
    def get_memory_stats(self) -> Dict[str, Any]:
        """获取记忆统计信息"""
        cursor = self.conn.cursor()
        
        stats = {}
        
        # 各表计数
        for table in ['episodic_memory', 'user_memory', 'memory_triggers', 'task_memory']:
            cursor.execute(f"SELECT COUNT(*) as count FROM {table}")
            stats[table] = cursor.fetchone()['count']
        
        # 平均遗忘分数
        cursor.execute("""
            SELECT AVG(forgetting_score) as avg_score 
            FROM episodic_memory
        """)
        result = cursor.fetchone()
        stats['avg_forgetting_score'] = result['avg_score'] if result else 0
        
        # 高风险记忆数
        cursor.execute("""
            SELECT COUNT(*) as count FROM episodic_memory 
            WHERE forgetting_score > 0.8
        """)
        stats['high_risk_memories'] = cursor.fetchone()['count']
        
        return stats
    
    def cleanup_old_memories(self, days: int = 30, priority_threshold: int = 2):
        """清理旧记忆（低优先级且长时间未访问）"""
        cursor = self.conn.cursor()
        
        cursor.execute("""
            DELETE FROM episodic_memory 
            WHERE priority <= ? 
            AND last_accessed < datetime('now', '-{} days')
        """.format(days), (priority_threshold,))
        
        deleted = cursor.rowcount
        self.conn.commit()
        return deleted
    
    def vacuum(self):
        """优化数据库空间"""
        self.conn.execute("VACUUM")


class JSONBackend:
    """
    JSON 文件后端（轻量级，适合单机部署）
    """
    
    def __init__(self, data_dir: str = "~/.memcore/data"):
        self.data_dir = os.path.expanduser(data_dir)
        os.makedirs(self.data_dir, exist_ok=True)
    
    def _get_file_path(self, category: str) -> str:
        return os.path.join(self.data_dir, f"{category}.json")
    
    def save(self, category: str, data: Dict):
        """保存数据到 JSON"""
        filepath = self._get_file_path(category)
        
        # 读取现有数据
        existing = {}
        if os.path.exists(filepath):
            with open(filepath, 'r', encoding='utf-8') as f:
                existing = json.load(f)
        
        # 更新
        existing.update(data)
        
        # 写回
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(existing, f, ensure_ascii=False, indent=2, default=str)
    
    def load(self, category: str) -> Dict:
        """从 JSON 读取数据"""
        filepath = self._get_file_path(category)
        
        if not os.path.exists(filepath):
            return {}
        
        with open(filepath, 'r', encoding='utf-8') as f:
            return json.load(f)
    
    def delete(self, category: str, key: str):
        """删除数据"""
        filepath = self._get_file_path(category)
        
        if not os.path.exists(filepath):
            return
        
        with open(filepath, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        if key in data:
            del data[key]
        
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2, default=str)


# 测试代码
if __name__ == "__main__":
    print("🧠 测试 Persistent Backend...")
    
    # 测试 SQLite 后端
    backend = SQLiteBackend(db_path="~/.memcore/test.db")
    
    # 测试统计
    stats = backend.get_memory_stats()
    print(f"📊 当前统计: {stats}")
    
    print("✅ 后端测试完成!")


path: requirements.txt
content: numpy>=1.20.0


path: vector_knowledge.py
content: """
Vector Knowledge Memory for Enhanced MemCore
向量知识记忆模块 - 支持语义检索
"""

import numpy as np
from typing import List, Dict, Any, Optional, Callable, Tuple
from dataclasses import dataclass, field
from datetime import datetime
import hashlib
import json


@dataclass
class KnowledgeDocument:
    """知识文档"""
    id: str
    content: str
    embedding: Optional[np.ndarray] = None
    metadata: Dict[str, Any] = field(default_factory=dict)
    source: str = ""
    created_at: datetime = field(default_factory=datetime.now)
    access_count: int = 0
    
    def touch(self):
        self.access_count += 1


class VectorKnowledgeMemory:
    """
    向量知识记忆
    支持语义相似度检索，无需精确关键词匹配
    """
    
    def __init__(
        self,
        embedding_fn: Optional[Callable[[str], List[float]]] = None,
        backend=None
    ):
        """
        Args:
            embedding_fn: 文本嵌入函数，如果为空则使用简单的词频向量
            backend: 可选的持久化后端
        """
        self.embedding_fn = embedding_fn or self._simple_embedding
        self.backend = backend
        self.documents: Dict[str, KnowledgeDocument] = {}
        self.embeddings: List[np.ndarray] = []
        self.doc_ids: List[str] = []
        
        # 如果有后端，加载已存储的知识
        if backend:
            self._load_from_backend()
    
    def _simple_embedding(self, text: str) -> List[float]:
        """
        简单的词频向量实现（无外部模型时使用）
        """
        # 简化的哈希向量
        hash_val = hashlib.md5(text.encode()).hexdigest()
        # 生成 128 维向量
        vec = [int(hash_val[i:i+2], 16) / 255.0 for i in range(0, 32, 2)]
        return vec
    
    def _cosine_similarity(self, vec1: np.ndarray, vec2: np.ndarray) -> float:
        """计算余弦相似度"""
        norm1 = np.linalg.norm(vec1)
        norm2 = np.linalg.norm(vec2)
        if norm1 == 0 or norm2 == 0:
            return 0.0
        return float(np.dot(vec1, vec2) / (norm1 * norm2))
    
    def add_knowledge(
        self,
        content: str,
        metadata: Optional[Dict] = None,
        source: str = "",
        doc_id: Optional[str] = None
    ) -> str:
        """
        添加知识
        
        Args:
            content: 知识内容
            metadata: 元数据（如主题、来源等）
            source: 来源标识
            doc_id: 自定义ID（默认生成）
            
        Returns:
            文档ID
        """
        doc_id = doc_id or f"know_{hashlib.md5(content.encode()).hexdigest()[:12]}"
        
        # 生成向量嵌入
        embedding = np.array(self.embedding_fn(content))
        
        doc = KnowledgeDocument(
            id=doc_id,
            content=content,
            embedding=embedding,
            metadata=metadata or {},
            source=source
        )
        
        self.documents[doc_id] = doc
        self.embeddings.append(embedding)
        self.doc_ids.append(doc_id)
        
        # 持久化
        if self.backend:
            self._save_to_backend(doc)
        
        return doc_id
    
    def query(
        self,
        query: str,
        top_k: int = 3,
        threshold: float = 0.0
    ) -> List[Tuple[KnowledgeDocument, float]]:
        """
        语义检索
        
        Args:
            query: 查询文本
            top_k: 返回最相似的k个结果
            threshold: 相似度阈值，低于此值的结果被过滤
            
        Returns:
            [(document, similarity_score), ...]
        """
        if not self.documents:
            return []
        
        # 生成查询向量
        query_vec = np.array(self.embedding_fn(query))
        
        # 计算所有相似度
        similarities = []
        for doc_id, doc in self.documents.items():
            if doc.embedding is not None:
                sim = self._cosine_similarity(query_vec, doc.embedding)
                if sim >= threshold:
                    similarities.append((doc, sim))
        
        # 按相似度排序
        similarities.sort(key=lambda x: x[1], reverse=True)
        
        # 返回 top_k
        results = similarities[:top_k]
        
        # 更新访问计数
        for doc, _ in results:
            doc.touch()
        
        return results
    
    def query_with_context(
        self,
        query: str,
        context_topics: List[str] = None,
        top_k: int = 3
    ) -> List[Tuple[KnowledgeDocument, float]]:
        """
        带上下文的检索
        结合语义相似度和主题匹配
        """
        results = self.query(query, top_k=top_k * 2)  # 先获取更多候选
        
        if not context_topics:
            return results[:top_k]
        
        # 增强与上下文主题相关的结果
        boosted_results = []
        for doc, sim in results:
            boost = 0
            doc_topics = doc.metadata.get('topics', [])
            for topic in context_topics:
                if topic in doc_topics:
                    boost += 0.1  # 每匹配一个主题加 0.1 分
            boosted_results.append((doc, min(1.0, sim + boost)))
        
        # 重新排序
        boosted_results.sort(key=lambda x: x[1], reverse=True)
        return boosted_results[:top_k]
    
    def get_document(self, doc_id: str) -> Optional[KnowledgeDocument]:
        """获取特定文档"""
        return self.documents.get(doc_id)
    
    def delete_document(self, doc_id: str) -> bool:
        """删除文档"""
        if doc_id not in self.documents:
            return False
        
        del self.documents[doc_id]
        
        # 更新向量索引
        self.embeddings = []
        self.doc_ids = []
        for did, doc in self.documents.items():
            self.embeddings.append(doc.embedding)
            self.doc_ids.append(did)
        
        return True
    
    def update_metadata(self, doc_id: str, metadata: Dict) -> bool:
        """更新文档元数据"""
        if doc_id not in self.documents:
            return False
        
        self.documents[doc_id].metadata.update(metadata)
        
        if self.backend:
            self._save_to_backend(self.documents[doc_id])
        
        return True
    
    def get_related_documents(
        self,
        doc_id: str,
        top_k: int = 5
    ) -> List[Tuple[KnowledgeDocument, float]]:
        """
        查找与指定文档相关的其他文档
        """
        doc = self.documents.get(doc_id)
        if not doc or doc.embedding is None:
            return []
        
        related = []
        for other_id, other_doc in self.documents.items():
            if other_id != doc_id and other_doc.embedding is not None:
                sim = self._cosine_similarity(doc.embedding, other_doc.embedding)
                related.append((other_doc, sim))
        
        related.sort(key=lambda x: x[1], reverse=True)
        return related[:top_k]
    
    def export_knowledge(self, topic: Optional[str] = None) -> List[Dict]:
        """
        导出知识（用于备份或迁移）
        """
        results = []
        for doc in self.documents.values():
            if topic is None or topic in doc.metadata.get('topics', []):
                results.append({
                    'id': doc.id,
                    'content': doc.content,
                    'metadata': doc.metadata,
                    'source': doc.source,
                    'created_at': doc.created_at.isoformat()
                })
        return results
    
    def import_knowledge(self, knowledge_list: List[Dict]):
        """
        导入知识
        """
        for item in knowledge_list:
            self.add_knowledge(
                content=item['content'],
                metadata=item.get('metadata', {}),
                source=item.get('source', 'imported'),
                doc_id=item.get('id')
            )
    
    def _save_to_backend(self, doc: KnowledgeDocument):
        """保存到后端"""
        if not self.backend:
            return
        
        data = {
            doc.id: {
                'content': doc.content,
                'embedding': doc.embedding.tolist() if doc.embedding is not None else None,
                'metadata': doc.metadata,
                'source': doc.source,
                'created_at': doc.created_at.isoformat(),
                'access_count': doc.access_count
            }
        }
        
        if hasattr(self.backend, 'save'):
            self.backend.save('knowledge', data)
        elif hasattr(self.backend, 'save_knowledge'):
            self.backend.save_knowledge(doc)
    
    def _load_from_backend(self):
        """从后端加载"""
        if not self.backend:
            return
        
        if hasattr(self.backend, 'load'):
            data = self.backend.load('knowledge')
            for doc_id, item in data.items():
                doc = KnowledgeDocument(
                    id=doc_id,
                    content=item['content'],
                    embedding=np.array(item['embedding']) if item.get('embedding') else None,
                    metadata=item.get('metadata', {}),
                    source=item.get('source', ''),
                    created_at=datetime.fromisoformat(item['created_at']),
                    access_count=item.get('access_count', 0)
                )
                self.documents[doc_id] = doc
                self.embeddings.append(doc.embedding)
                self.doc_ids.append(doc_id)
    
    def get_stats(self) -> Dict[str, Any]:
        """获取统计信息"""
        return {
            'total_documents': len(self.documents),
            'total_embeddings': len(self.embeddings),
            'avg_document_length': sum(len(d.content) for d in self.documents.values()) / max(len(self.documents), 1),
            'top_sources': self._count_sources()
        }
    
    def _count_sources(self) -> Dict[str, int]:
        """统计来源分布"""
        sources = {}
        for doc in self.documents.values():
            src = doc.source or 'unknown'
            sources[src] = sources.get(src, 0) + 1
        return sources


# 集成 OpenAI Embedding 的示例
class OpenAIEmbeddingWrapper:
    """OpenAI Embedding 包装器"""
    
    def __init__(self, [REDACTED_SECRET] = None):
        self.[REDACTED_SECRET]
        try:
            import openai
            self.client = openai.OpenAI([REDACTED_SECRET])
        except ImportError:
            raise ImportError("Please install openai: pip install openai")
    
    def __call__(self, text: str) -> List[float]:
        """生成嵌入向量"""
        response = self.client.embeddings.create(
            input=text,
            model="text-embedding-3-small"
        )
        return response.data[0].embedding


# 测试代码
if __name__ == "__main__":
    print("🧠 测试 Vector Knowledge Memory...")
    
    # 创建知识库
    knowledge = VectorKnowledgeMemory()
    
    # 添加知识
    knowledge.add_knowledge(
        content="MemCore 是一个五层记忆架构的 AI Agent 记忆系统",
        metadata={"topics": ["MemCore", "AI", "architecture"]},
        source="github"
    )
    
    knowledge.add_knowledge(
        content="遗忘曲线基于艾宾浩斯记忆公式 R = e^(-t/S)",
        metadata={"topics": ["forgetting_curve", "psychology"]},
        source="wikipedia"
    )
    
    knowledge.add_knowledge(
        content="情景记忆可以记录具体事件和结论",
        metadata={"topics": ["episodic_memory", "MemCore"]},
        source="docs"
    )
    
    # 测试查询
    print("\n🔍 测试查询 '记忆架构':")
    results = knowledge.query("记忆架构是什么", top_k=2)
    for doc, score in results:
        print(f"   - {doc.content[:50]}... (相似度: {score:.3f})")
    
    # 测试上下文检索
    print("\n🔍 测试带上下文的查询 '记忆' (上下文: MemCore):")
    results = knowledge.query_with_context(
        "记忆系统",
        context_topics=["MemCore"],
        top_k=2
    )
    for doc, score in results:
        print(f"   - {doc.content[:50]}... (增强后相似度: {score:.3f})")
    
    print("\n📊 统计:", knowledge.get_stats())
    print("✅ 向量知识测试完成!")


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)