mindforge-memory 6.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. MindForge.py +20 -0
  2. mindforge/__init__.py +111 -0
  3. mindforge/adapters/__init__.py +18 -0
  4. mindforge/adapters/claude_adapter.py +84 -0
  5. mindforge/adapters/crewai_memory.py +76 -0
  6. mindforge/adapters/generic_api.py +183 -0
  7. mindforge/adapters/langgraph_store.py +463 -0
  8. mindforge/adapters/openclaw_adapter.py +91 -0
  9. mindforge/api/__init__.py +1 -0
  10. mindforge/api/server.py +1567 -0
  11. mindforge/cli/__init__.py +1 -0
  12. mindforge/cli/main.py +13607 -0
  13. mindforge/core/__init__.py +37 -0
  14. mindforge/core/embedding.py +847 -0
  15. mindforge/core/encryption.py +597 -0
  16. mindforge/core/indexer.py +363 -0
  17. mindforge/core/mindforge.py +6298 -0
  18. mindforge/core/paths.py +43 -0
  19. mindforge/core/query.py +501 -0
  20. mindforge/core/storage.py +18656 -0
  21. mindforge/core/types.py +314 -0
  22. mindforge/core/version.py +56 -0
  23. mindforge/daemon/__init__.py +0 -0
  24. mindforge/daemon/server.py +277 -0
  25. mindforge/mcp/__init__.py +4 -0
  26. mindforge/mcp/server.py +2559 -0
  27. mindforge/modules/__init__.py +138 -0
  28. mindforge/modules/categorizer.py +151 -0
  29. mindforge/modules/conflict_detector.py +356 -0
  30. mindforge/modules/connectors.py +331 -0
  31. mindforge/modules/context_window.py +337 -0
  32. mindforge/modules/event_bus.py +572 -0
  33. mindforge/modules/evolution.py +210 -0
  34. mindforge/modules/experience.py +402 -0
  35. mindforge/modules/federated.py +722 -0
  36. mindforge/modules/federated_acl.py +393 -0
  37. mindforge/modules/follow_up.py +315 -0
  38. mindforge/modules/hybrid_search.py +565 -0
  39. mindforge/modules/importer.py +374 -0
  40. mindforge/modules/integrator.py +196 -0
  41. mindforge/modules/intent_router.py +359 -0
  42. mindforge/modules/knowledge_graph.py +395 -0
  43. mindforge/modules/memory_compressor.py +592 -0
  44. mindforge/modules/memory_decay.py +474 -0
  45. mindforge/modules/memory_passport.py +250 -0
  46. mindforge/modules/multi_agent.py +534 -0
  47. mindforge/modules/multimodal.py +304 -0
  48. mindforge/modules/outcome_learning.py +186 -0
  49. mindforge/modules/personality.py +275 -0
  50. mindforge/modules/principled_forgetting.py +258 -0
  51. mindforge/modules/privacy.py +736 -0
  52. mindforge/modules/recall.py +263 -0
  53. mindforge/modules/session_focus.py +305 -0
  54. mindforge/modules/share_conflict.py +521 -0
  55. mindforge/modules/skill_extractor.py +340 -0
  56. mindforge/modules/skill_pack.py +205 -0
  57. mindforge/modules/timeline_viz.py +206 -0
  58. mindforge/modules/v6.py +931 -0
  59. mindforge_memory-6.4.1.dist-info/METADATA +281 -0
  60. mindforge_memory-6.4.1.dist-info/RECORD +64 -0
  61. mindforge_memory-6.4.1.dist-info/WHEEL +5 -0
  62. mindforge_memory-6.4.1.dist-info/entry_points.txt +3 -0
  63. mindforge_memory-6.4.1.dist-info/licenses/LICENSE +21 -0
  64. mindforge_memory-6.4.1.dist-info/top_level.txt +2 -0
MindForge.py ADDED
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ MindForge - AI Agent 终身记忆系统
4
+ =======================================
5
+ 四层记忆架构 · 知识图谱引擎 · 多模态支持 · 人格化记忆 · 联邦网络 · AI短剧记忆
6
+
7
+ 兼容入口(自 v5.8.13 起):全部源码已迁入 `mindforge.*` 命名空间,
8
+ 本文件仅为向后兼容保留,使 `from MindForge import MindForge` 在 pip install
9
+ 后仍然可用。新代码请统一使用 `from mindforge import MindForge`。
10
+ """
11
+
12
+ from mindforge import * # noqa: F401,F403
13
+ from mindforge import ( # noqa: F401
14
+ __version__,
15
+ VERSION_INFO,
16
+ NEXT_MAJOR_TARGET,
17
+ )
18
+
19
+ __author__ = "MindForge Project"
20
+ __license__ = "MIT"
mindforge/__init__.py ADDED
@@ -0,0 +1,111 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ MindForge — AI Agent 终身记忆系统
4
+
5
+ 四层记忆架构 · 知识图谱引擎 · 多模态支持 · 人格化记忆 · 联邦网络 · AI短剧记忆
6
+
7
+ 包入口(mindforge.* 命名空间):自 v5.8.13 起全部源码统一位于 mindforge/
8
+ 子包下,不再以 core/modules/mcp/api/cli/adapters 等顶层名称安装进
9
+ site-packages,避免与其它库冲突。旧式 `from MindForge import ...` 仍可通过
10
+ 仓库根目录的 MindForge.py 兼容模块使用(不推荐新代码使用)。
11
+ """
12
+
13
+ from .core import (
14
+ MindForge,
15
+ MemoryEntry,
16
+ MemoryLayer,
17
+ PrivacyLevel,
18
+ Importance,
19
+ MemoryType,
20
+ MemoryConfig,
21
+ StorageEngine,
22
+ EncryptionEngine,
23
+ IndexEngine,
24
+ QueryEngine,
25
+ AuditRecord,
26
+ MemoryChunk,
27
+ RecallResult,
28
+ VectorIndex,
29
+ init_engine,
30
+ get_engine,
31
+ )
32
+ from .modules import (
33
+ RecallEngine,
34
+ RecallConfig,
35
+ KnowledgeGraph,
36
+ MemoryEvolution,
37
+ PersonalityEngine,
38
+ MultimodalMemory,
39
+ FederatedMemory,
40
+ TaxonomyManager,
41
+ PrivacyEngine,
42
+ MemoryIntegrator,
43
+ # v6.0.0 扩展端口预留(默认不启用,仅暴露发现/注册入口)
44
+ V6_TARGET_VERSION,
45
+ V6Capability,
46
+ V6Status,
47
+ V6Port,
48
+ MultiAgentCollaborationPort,
49
+ MultiAgentAdapterPort,
50
+ MemoryPreviewPort,
51
+ create_multi_agent_adapter,
52
+ register_v6_port,
53
+ get_v6_port,
54
+ list_v6_ports,
55
+ v6_status,
56
+ )
57
+ from .modules.event_bus import EventBus
58
+ from .modules.experience import ExperienceCase, SkillStore
59
+ from .core.version import __version__, VERSION_INFO, NEXT_MAJOR_TARGET
60
+
61
+ __author__ = "MindForge Project"
62
+ __license__ = "MIT"
63
+
64
+ __all__ = [
65
+ "MindForge",
66
+ "MemoryEntry",
67
+ "MemoryLayer",
68
+ "PrivacyLevel",
69
+ "Importance",
70
+ "MemoryType",
71
+ "MemoryConfig",
72
+ "StorageEngine",
73
+ "EncryptionEngine",
74
+ "IndexEngine",
75
+ "QueryEngine",
76
+ "AuditRecord",
77
+ "MemoryChunk",
78
+ "RecallResult",
79
+ "VectorIndex",
80
+ "init_engine",
81
+ "get_engine",
82
+ "RecallEngine",
83
+ "RecallConfig",
84
+ "KnowledgeGraph",
85
+ "MemoryEvolution",
86
+ "PersonalityEngine",
87
+ "MultimodalMemory",
88
+ "FederatedMemory",
89
+ "TaxonomyManager",
90
+ "PrivacyEngine",
91
+ "MemoryIntegrator",
92
+ "EventBus",
93
+ "ExperienceCase",
94
+ "SkillStore",
95
+ "__version__",
96
+ "VERSION_INFO",
97
+ "NEXT_MAJOR_TARGET",
98
+ # v6.0.0 端口预留
99
+ "V6_TARGET_VERSION",
100
+ "V6Capability",
101
+ "V6Status",
102
+ "V6Port",
103
+ "MultiAgentCollaborationPort",
104
+ "MultiAgentAdapterPort",
105
+ "MemoryPreviewPort",
106
+ "create_multi_agent_adapter",
107
+ "register_v6_port",
108
+ "get_v6_port",
109
+ "list_v6_ports",
110
+ "v6_status",
111
+ ]
@@ -0,0 +1,18 @@
1
+ """
2
+ MindForge v5.0 适配器
3
+ OpenClaw · Claude Code · 通用 API · LangGraph Store · CrewAI Memory
4
+ """
5
+
6
+ from .openclaw_adapter import OpenClawAdapter
7
+ from .generic_api import GenericAPIAdapter
8
+ from .claude_adapter import ClaudeCodeAdapter
9
+ from .langgraph_store import MindForgeStore
10
+ from .crewai_memory import CrewAIMemory
11
+
12
+ __all__ = [
13
+ "OpenClawAdapter",
14
+ "GenericAPIAdapter",
15
+ "ClaudeCodeAdapter",
16
+ "MindForgeStore",
17
+ "CrewAIMemory",
18
+ ]
@@ -0,0 +1,84 @@
1
+ """
2
+ MindForge v5.0 Claude Code 适配器
3
+ """
4
+
5
+ import os
6
+ from typing import List, Dict, Optional
7
+
8
+
9
+ class ClaudeCodeAdapter:
10
+ """Claude Code 记忆适配器"""
11
+
12
+ def __init__(self, MindForge):
13
+ self.cm = MindForge
14
+ self.session_id = os.environ.get("CLAUDE_SESSION_ID", "claude")
15
+ self.agent_id = "claude_code"
16
+
17
+ @classmethod
18
+ def from_env(cls):
19
+ """从环境变量创建"""
20
+ from mindforge.core import MindForge, MemoryConfig
21
+
22
+ db_path = os.environ.get("MindForge_DB_PATH", "./data/memory.db")
23
+ key_file = os.environ.get("MindForge_KEY_FILE", "./data/.key")
24
+ encrypted = os.environ.get("MindForge_ENCRYPTED", "true").lower() == "true"
25
+
26
+ config = MemoryConfig(
27
+ db_path=db_path,
28
+ key_file=key_file,
29
+ encrypted=encrypted,
30
+ )
31
+ cm = MindForge(config=config)
32
+ return cls(cm)
33
+
34
+ def remember(self, content: str, tags: Optional[List[str]] = None) -> str:
35
+ """记住某件事"""
36
+ entry = self.cm.add(
37
+ content=content,
38
+ tags=tags or [],
39
+ source_agent=self.agent_id,
40
+ source_session=self.session_id,
41
+ )
42
+ return entry.id
43
+
44
+ def recall(self, query: str, limit: int = 5) -> List[str]:
45
+ """回忆相关内容"""
46
+ result = self.cm.search(
47
+ query=query,
48
+ max_results=limit,
49
+ agent_id=self.agent_id,
50
+ session_id=self.session_id,
51
+ )
52
+ return [chunk.content for chunk in result.chunks]
53
+
54
+ def forget(self, memory_id: str) -> bool:
55
+ """忘记某件事"""
56
+ return self.cm.delete(memory_id, self.agent_id, self.session_id)
57
+
58
+ def get_context(self, current_task: str, limit: int = 10) -> str:
59
+ """获取相关上下文"""
60
+ result = self.cm.search(
61
+ query=current_task,
62
+ max_results=limit,
63
+ agent_id=self.agent_id,
64
+ session_id=self.session_id,
65
+ )
66
+
67
+ context_parts = ["# Relevant Memory\n"]
68
+ for i, chunk in enumerate(result.chunks, 1):
69
+ context_parts.append(f"## Memory {i} ({chunk.category})\n")
70
+ context_parts.append(f"{chunk.content}\n")
71
+
72
+ return "\n".join(context_parts)
73
+
74
+ def learn_user_preference(self, user_message: str, response: str):
75
+ """学习用户偏好"""
76
+ from mindforge.modules.personality import PersonalityEngine
77
+ pe = PersonalityEngine(self.cm.storage)
78
+ pe.learn_from_interaction("default", user_message, response)
79
+
80
+ def get_user_style(self) -> Dict:
81
+ """获取用户风格偏好"""
82
+ from mindforge.modules.personality import PersonalityEngine
83
+ pe = PersonalityEngine(self.cm.storage)
84
+ return pe.get_recommended_style()
@@ -0,0 +1,76 @@
1
+ # -*- coding: utf-8 -*-
2
+ """CrewAI Memory 适配器(v5.8.4 新增)
3
+
4
+ 把 MindForge 包装为 CrewAI 生态的长期记忆后端(Memory 接口):
5
+
6
+ from mindforge.adapters.crewai_memory import CrewAIMemory
7
+
8
+ memory = CrewAIMemory(mindforge, namespace="crew_travel")
9
+ memory.save("用户偏好靠窗座位", metadata={"trip": "tokyo"})
10
+ memory.search("座位偏好", limit=3)
11
+
12
+ 设计要点:
13
+ - 零硬依赖:未安装 crewai 时类仍可导入(基类回退 object)。
14
+ - 写:save() -> MindForge add(),namespace 编码进 category,metadata 扁平为 tags;
15
+ - 读:search() -> MindForge 混合检索(mf.search().chunks 解密明文路径);
16
+ - reset() 仅清空本 namespace 条目(list 定位 id 后逐条 delete),不影响其他应用。
17
+ """
18
+ from __future__ import annotations
19
+
20
+ from typing import Any, Dict, List, Optional
21
+
22
+ try:
23
+ from crewai.memory.memory import Memory as _CrewMemory # type: ignore
24
+ _CREWAI_AVAILABLE = True
25
+ except Exception: # pragma: no cover - 无 crewai 环境回退
26
+ _CrewMemory = object # type: ignore
27
+ _CREWAI_AVAILABLE = False
28
+
29
+
30
+ class CrewAIMemory(_CrewMemory):
31
+ """CrewAI Memory 协议的 MindForge 后端(v5.8.4)。"""
32
+
33
+ def __init__(self, mindforge, namespace: str = "crewai"):
34
+ self.mf = mindforge
35
+ self.namespace = namespace
36
+
37
+ def save(self, value: Any, metadata: Optional[Dict[str, Any]] = None) -> None:
38
+ """保存一条记忆。value 序列化为文本,metadata 扁平为 tags。"""
39
+ metadata = metadata or {}
40
+ tags = ["%s:%s" % (k, v) for k, v in metadata.items()
41
+ if isinstance(v, (str, int, float, bool))]
42
+ self.mf.add(
43
+ str(value),
44
+ category=self.namespace,
45
+ tags=tags,
46
+ source_agent="crewai",
47
+ )
48
+
49
+ def search(self, query: str, limit: int = 3,
50
+ filters: Optional[Dict[str, Any]] = None) -> List[Dict[str, Any]]:
51
+ """搜索记忆,返回 CrewAI 风格 list[dict](context 为解密明文)。"""
52
+ rr = self.mf.search(query, max_results=limit,
53
+ categories=[self.namespace])
54
+ results: List[Dict[str, Any]] = []
55
+ for c in (rr.chunks or []):
56
+ results.append({
57
+ "context": getattr(c, "content", "") or "",
58
+ "metadata": {
59
+ "id": getattr(c, "memory_id", ""),
60
+ "category": getattr(c, "category", self.namespace),
61
+ "tags": getattr(c, "tags", []),
62
+ },
63
+ })
64
+ return results
65
+
66
+ def reset(self) -> None:
67
+ """清空本 namespace 的全部记忆(不影响其他应用)。循环删直到空。"""
68
+ for _ in range(100): # 安全上限,防意外死循环
69
+ rows = self.mf.list(category=self.namespace, limit=500) or []
70
+ if not rows:
71
+ return
72
+ for h in rows:
73
+ self.mf.delete(getattr(h, "id", ""))
74
+
75
+
76
+ __all__ = ["CrewAIMemory", "_CREWAI_AVAILABLE"]
@@ -0,0 +1,183 @@
1
+ """
2
+ MindForge v5.0 通用 API 适配器
3
+ REST API / SDK 风格接口
4
+ """
5
+
6
+ from typing import List, Dict, Optional, Callable, Any
7
+
8
+
9
+ class GenericAPIAdapter:
10
+ """通用 API 适配器"""
11
+
12
+ def __init__(self, MindForge):
13
+ self.cm = MindForge
14
+ self._handlers: Dict[str, Callable] = {}
15
+ self._register_default_handlers()
16
+
17
+ def _register_default_handlers(self):
18
+ self._handlers = {
19
+ "memory.add": self._handle_add,
20
+ "memory.get": self._handle_get,
21
+ "memory.search": self._handle_search,
22
+ "memory.list": self._handle_list,
23
+ "memory.update": self._handle_update,
24
+ "memory.delete": self._handle_delete,
25
+ "stats.get": self._handle_stats,
26
+ "graph.stats": self._handle_graph_stats,
27
+ "graph.related": self._handle_graph_related,
28
+ "personality.profile": self._handle_personality,
29
+ "evolution.consolidate": self._handle_consolidate,
30
+ }
31
+
32
+ def handle_request(self, request: Dict) -> Dict:
33
+ """处理 API 请求
34
+
35
+ P2 #19 修复:
36
+ - 校验 request 结构(action 必选且为字符串)
37
+ - 异常信息脱敏,不暴露内部调用栈细节
38
+ """
39
+ if not isinstance(request, dict):
40
+ return {"success": False, "error": "Invalid request format"}
41
+
42
+ action = request.get("action", "")
43
+ params = request.get("params", {})
44
+
45
+ if not action or not isinstance(action, str):
46
+ return {"success": False, "error": "Missing required field: action"}
47
+ if not isinstance(params, dict):
48
+ return {"success": False, "error": "Invalid params format"}
49
+
50
+ handler = self._handlers.get(action)
51
+ if not handler:
52
+ return {
53
+ "success": False,
54
+ "error": f"Unknown action: {action}",
55
+ }
56
+
57
+ try:
58
+ result = handler(params)
59
+ return {
60
+ "success": True,
61
+ "data": result,
62
+ }
63
+ except (ValueError, TypeError) as e:
64
+ # 预期内的错误:返回消息(用户输入类)
65
+ return {
66
+ "success": False,
67
+ "error": str(e),
68
+ }
69
+ except Exception as e:
70
+ # 未预期的错误:脱敏返回,防止内部细节泄露
71
+ import logging as _logging
72
+ _logging.getLogger(__name__).exception("API handler error: %s", action)
73
+ return {
74
+ "success": False,
75
+ "error": "Internal error",
76
+ }
77
+
78
+ @staticmethod
79
+ def _require(params: Dict, field: str, error_msg: str = "") -> Any:
80
+ """校验必需字段,缺失时返回友好错误"""
81
+ if field not in params:
82
+ raise ValueError(error_msg or f"Missing required field: {field}")
83
+ return params[field]
84
+
85
+ def _handle_add(self, params: Dict) -> Dict:
86
+ entry = self.cm.add(
87
+ content=self._require(params, "content"),
88
+ category=params.get("category", "general"),
89
+ tags=params.get("tags", []),
90
+ source_agent=params.get("agent", "api"),
91
+ source_session=params.get("session", "api"),
92
+ )
93
+ return entry.to_dict()
94
+
95
+ def _handle_get(self, params: Dict) -> Optional[Dict]:
96
+ entry = self.cm.get(
97
+ self._require(params, "id"),
98
+ actor=params.get("actor", ""), # v5.7.3:未传 actor 视同本机内部调用
99
+ session_id=params.get("session_id", ""),
100
+ )
101
+ return entry.to_dict() if entry else None
102
+
103
+ def _handle_search(self, params: Dict) -> Dict:
104
+ result = self.cm.search(
105
+ query=params["query"],
106
+ max_results=params.get("limit", 10),
107
+ categories=params.get("categories"),
108
+ agent_id=params.get("actor", ""), # v5.7.3:未传 actor 视同本机内部调用
109
+ session_id=params.get("session_id", ""),
110
+ )
111
+ return {
112
+ "total": result.total_found,
113
+ "time_ms": result.query_time_ms,
114
+ "results": [
115
+ {
116
+ "id": c.memory_id,
117
+ "content": c.content,
118
+ "category": c.category,
119
+ "relevance": c.relevance_score,
120
+ }
121
+ for c in result.chunks
122
+ ],
123
+ }
124
+
125
+ def _handle_list(self, params: Dict) -> List[Dict]:
126
+ # F1 修复:适配器列表入口接入隐私过滤(params.actor / params.session_id)。
127
+ # 未传 actor 时保持原有"返回全部"语义,兼容既有集成方。
128
+ entries = self.cm.list(
129
+ category=params.get("category"),
130
+ limit=params.get("limit", 50),
131
+ offset=params.get("offset", 0),
132
+ actor=str(params.get("actor") or ""),
133
+ session_id=str(params.get("session_id") or ""),
134
+ )
135
+ return [e.to_dict() for e in entries]
136
+
137
+ def _handle_update(self, params: Dict) -> bool:
138
+ return self.cm.update(
139
+ memory_id=self._require(params, "id"),
140
+ content=params.get("content"),
141
+ category=params.get("category"),
142
+ tags=params.get("tags"),
143
+ actor=params.get("actor", ""), # v5.7.3:未传 actor 视同本机内部调用
144
+ session_id=params.get("session_id", ""),
145
+ )
146
+
147
+ def _handle_delete(self, params: Dict) -> bool:
148
+ return self.cm.delete(
149
+ self._require(params, "id"),
150
+ actor=params.get("actor", ""), # v5.7.3:未传 actor 视同本机内部调用
151
+ session_id=params.get("session_id", ""),
152
+ )
153
+
154
+ def _handle_stats(self, params: Dict) -> Dict:
155
+ return self.cm.stats()
156
+
157
+ def _handle_graph_stats(self, params: Dict) -> Dict:
158
+ from mindforge.modules.knowledge_graph import KnowledgeGraph
159
+ kg = KnowledgeGraph(storage=self.cm.storage)
160
+ return kg.get_entity_stats()
161
+
162
+ def _handle_graph_related(self, params: Dict) -> List:
163
+ from mindforge.modules.knowledge_graph import KnowledgeGraph
164
+ kg = KnowledgeGraph(storage=self.cm.storage)
165
+ related = kg.get_related_entities(
166
+ self._require(params, "entity"),
167
+ depth=params.get("depth", 2),
168
+ )
169
+ return [{"name": n, "relation": r, "weight": w} for n, r, w in related]
170
+
171
+ def _handle_personality(self, params: Dict) -> Dict:
172
+ from mindforge.modules.personality import PersonalityEngine
173
+ pe = PersonalityEngine(self.cm.storage)
174
+ return pe.get_recommended_style(params.get("user_id", "default"))
175
+
176
+ def _handle_consolidate(self, params: Dict) -> Dict:
177
+ from mindforge.modules.evolution import MemoryEvolution
178
+ evo = MemoryEvolution(self.cm.storage)
179
+ return evo.consolidate()
180
+
181
+ def register_handler(self, action: str, handler: Callable):
182
+ """注册自定义处理器"""
183
+ self._handlers[action] = handler