iflow-mcp_hanw39_reasoning-bank-mcp 0.2.0__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.
- iflow_mcp_hanw39_reasoning_bank_mcp-0.2.0.dist-info/METADATA +599 -0
- iflow_mcp_hanw39_reasoning_bank_mcp-0.2.0.dist-info/RECORD +55 -0
- iflow_mcp_hanw39_reasoning_bank_mcp-0.2.0.dist-info/WHEEL +4 -0
- iflow_mcp_hanw39_reasoning_bank_mcp-0.2.0.dist-info/entry_points.txt +2 -0
- iflow_mcp_hanw39_reasoning_bank_mcp-0.2.0.dist-info/licenses/LICENSE +21 -0
- src/__init__.py +16 -0
- src/__main__.py +6 -0
- src/config.py +266 -0
- src/deduplication/__init__.py +19 -0
- src/deduplication/base.py +88 -0
- src/deduplication/factory.py +60 -0
- src/deduplication/strategies/__init__.py +1 -0
- src/deduplication/strategies/semantic_dedup.py +187 -0
- src/default_config.yaml +121 -0
- src/initializers/__init__.py +50 -0
- src/initializers/base.py +196 -0
- src/initializers/embedding_initializer.py +22 -0
- src/initializers/llm_initializer.py +22 -0
- src/initializers/memory_manager_initializer.py +55 -0
- src/initializers/retrieval_initializer.py +32 -0
- src/initializers/storage_initializer.py +22 -0
- src/initializers/tools_initializer.py +48 -0
- src/llm/__init__.py +10 -0
- src/llm/base.py +61 -0
- src/llm/factory.py +75 -0
- src/llm/providers/__init__.py +12 -0
- src/llm/providers/anthropic.py +62 -0
- src/llm/providers/dashscope.py +76 -0
- src/llm/providers/openai.py +76 -0
- src/merge/__init__.py +22 -0
- src/merge/base.py +89 -0
- src/merge/factory.py +60 -0
- src/merge/strategies/__init__.py +1 -0
- src/merge/strategies/llm_merge.py +170 -0
- src/merge/strategies/voting_merge.py +108 -0
- src/prompts/__init__.py +21 -0
- src/prompts/formatters.py +74 -0
- src/prompts/templates.py +184 -0
- src/retrieval/__init__.py +8 -0
- src/retrieval/base.py +37 -0
- src/retrieval/factory.py +55 -0
- src/retrieval/strategies/__init__.py +8 -0
- src/retrieval/strategies/cosine_retrieval.py +47 -0
- src/retrieval/strategies/hybrid_retrieval.py +155 -0
- src/server.py +306 -0
- src/services/__init__.py +5 -0
- src/services/memory_manager.py +403 -0
- src/storage/__init__.py +45 -0
- src/storage/backends/json_backend.py +290 -0
- src/storage/base.py +150 -0
- src/tools/__init__.py +8 -0
- src/tools/extract_memory.py +285 -0
- src/tools/retrieve_memory.py +139 -0
- src/utils/__init__.py +7 -0
- src/utils/similarity.py +54 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"""JSON 存储后端实现"""
|
|
2
|
+
import json
|
|
3
|
+
import asyncio
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import List, Dict, Optional
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
import numpy as np
|
|
8
|
+
from threading import Lock
|
|
9
|
+
|
|
10
|
+
from ..base import StorageBackend
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class JSONStorageBackend(StorageBackend):
|
|
14
|
+
"""JSON 文件存储后端"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, config: Dict):
|
|
17
|
+
self.memories_path = Path(config.get("memories_path", "data/memories.json")).expanduser()
|
|
18
|
+
self.embeddings_path = Path(config.get("embeddings_path", "data/embeddings.json")).expanduser()
|
|
19
|
+
self.archived_path = Path(config.get("archived_path", "data/archived_memories.json")).expanduser()
|
|
20
|
+
self._lock = Lock()
|
|
21
|
+
|
|
22
|
+
# Store retrieval strategy reference (injected later)
|
|
23
|
+
self.retrieval_strategy = None
|
|
24
|
+
|
|
25
|
+
# 初始化文件
|
|
26
|
+
self._initialize_files()
|
|
27
|
+
|
|
28
|
+
def _initialize_files(self):
|
|
29
|
+
"""初始化 JSON 文件"""
|
|
30
|
+
# 创建所有必要的目录
|
|
31
|
+
self.memories_path.parent.mkdir(parents=True, exist_ok=True)
|
|
32
|
+
self.embeddings_path.parent.mkdir(parents=True, exist_ok=True)
|
|
33
|
+
self.archived_path.parent.mkdir(parents=True, exist_ok=True)
|
|
34
|
+
|
|
35
|
+
# 初始化 memories 文件
|
|
36
|
+
if not self.memories_path.exists():
|
|
37
|
+
self._save_memories({
|
|
38
|
+
"version": "1.0",
|
|
39
|
+
"total_count": 0,
|
|
40
|
+
"memories": []
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
# 初始化 embeddings 文件
|
|
44
|
+
if not self.embeddings_path.exists():
|
|
45
|
+
self._save_embeddings({
|
|
46
|
+
"version": "1.0",
|
|
47
|
+
"embedding_model": "unknown",
|
|
48
|
+
"embedding_dim": 0,
|
|
49
|
+
"embeddings": {}
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
# 注意:archived 文件是可选的,只在需要时创建(在 archive_memories 方法中)
|
|
53
|
+
# 这里只确保父目录存在
|
|
54
|
+
|
|
55
|
+
def _load_memories(self) -> Dict:
|
|
56
|
+
"""加载记忆数据"""
|
|
57
|
+
with self._lock:
|
|
58
|
+
with open(self.memories_path, 'r', encoding='utf-8') as f:
|
|
59
|
+
return json.load(f)
|
|
60
|
+
|
|
61
|
+
def _save_memories(self, data: Dict):
|
|
62
|
+
"""保存记忆数据"""
|
|
63
|
+
with self._lock:
|
|
64
|
+
with open(self.memories_path, 'w', encoding='utf-8') as f:
|
|
65
|
+
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
66
|
+
|
|
67
|
+
def _load_embeddings(self) -> Dict:
|
|
68
|
+
"""加载嵌入数据"""
|
|
69
|
+
with self._lock:
|
|
70
|
+
with open(self.embeddings_path, 'r', encoding='utf-8') as f:
|
|
71
|
+
return json.load(f)
|
|
72
|
+
|
|
73
|
+
def _save_embeddings(self, data: Dict):
|
|
74
|
+
"""保存嵌入数据"""
|
|
75
|
+
with self._lock:
|
|
76
|
+
with open(self.embeddings_path, 'w', encoding='utf-8') as f:
|
|
77
|
+
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
78
|
+
|
|
79
|
+
async def add_memory(self, memory: Dict, embedding: List[float]):
|
|
80
|
+
"""添加新记忆"""
|
|
81
|
+
# 添加到 memories.json
|
|
82
|
+
memories_data = self._load_memories()
|
|
83
|
+
memories_data["memories"].append(memory)
|
|
84
|
+
memories_data["total_count"] = len(memories_data["memories"])
|
|
85
|
+
memories_data["last_updated"] = memory["timestamp"]
|
|
86
|
+
self._save_memories(memories_data)
|
|
87
|
+
|
|
88
|
+
# 添加到 embeddings.json
|
|
89
|
+
embeddings_data = self._load_embeddings()
|
|
90
|
+
embeddings_data["embeddings"][memory["memory_id"]] = {
|
|
91
|
+
"query_text": memory["query"],
|
|
92
|
+
"vector": embedding,
|
|
93
|
+
"created_at": memory["timestamp"]
|
|
94
|
+
}
|
|
95
|
+
embeddings_data["last_updated"] = memory["timestamp"]
|
|
96
|
+
self._save_embeddings(embeddings_data)
|
|
97
|
+
|
|
98
|
+
async def get_memory_by_id(self, memory_id: str) -> Optional[Dict]:
|
|
99
|
+
"""根据 ID 获取记忆"""
|
|
100
|
+
memories_data = self._load_memories()
|
|
101
|
+
for mem in memories_data["memories"]:
|
|
102
|
+
if mem["memory_id"] == memory_id:
|
|
103
|
+
return mem
|
|
104
|
+
return None
|
|
105
|
+
|
|
106
|
+
async def get_all_memories(self, agent_id: str = None) -> List[Dict]:
|
|
107
|
+
"""
|
|
108
|
+
获取所有记忆
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
agent_id: Agent ID,用于过滤。None 表示获取所有记忆
|
|
112
|
+
"""
|
|
113
|
+
memories_data = self._load_memories()
|
|
114
|
+
all_memories = memories_data["memories"]
|
|
115
|
+
|
|
116
|
+
# 如果指定了 agent_id,只返回匹配的记忆
|
|
117
|
+
if agent_id is not None:
|
|
118
|
+
return [m for m in all_memories if m.get("agent_id") == agent_id]
|
|
119
|
+
|
|
120
|
+
# 否则返回所有记忆
|
|
121
|
+
return all_memories
|
|
122
|
+
|
|
123
|
+
async def get_all_embeddings(self, agent_id: str = None) -> Dict[str, np.ndarray]:
|
|
124
|
+
"""
|
|
125
|
+
获取所有嵌入向量
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
agent_id: Agent ID,用于过滤。None 表示获取所有嵌入
|
|
129
|
+
"""
|
|
130
|
+
embeddings_data = self._load_embeddings()
|
|
131
|
+
|
|
132
|
+
if agent_id is None:
|
|
133
|
+
# 返回所有
|
|
134
|
+
return {
|
|
135
|
+
mem_id: np.array(data["vector"])
|
|
136
|
+
for mem_id, data in embeddings_data["embeddings"].items()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# 需要先获取记忆列表,找出属于该 agent 的 memory_id
|
|
140
|
+
memories = await self.get_all_memories(agent_id)
|
|
141
|
+
memory_ids = {m["memory_id"] for m in memories}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
mem_id: np.array(data["vector"])
|
|
145
|
+
for mem_id, data in embeddings_data["embeddings"].items()
|
|
146
|
+
if mem_id in memory_ids
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async def update_retrieval_stats(self, memory_id: str, timestamp: str):
|
|
150
|
+
"""更新检索统计"""
|
|
151
|
+
memories_data = self._load_memories()
|
|
152
|
+
for mem in memories_data["memories"]:
|
|
153
|
+
if mem["memory_id"] == memory_id:
|
|
154
|
+
mem["retrieval_count"] = mem.get("retrieval_count", 0) + 1
|
|
155
|
+
mem["last_retrieved"] = timestamp
|
|
156
|
+
break
|
|
157
|
+
self._save_memories(memories_data)
|
|
158
|
+
|
|
159
|
+
async def get_stats(self) -> Dict:
|
|
160
|
+
"""获取统计信息"""
|
|
161
|
+
memories_data = self._load_memories()
|
|
162
|
+
memories = memories_data["memories"]
|
|
163
|
+
|
|
164
|
+
success_count = sum(1 for m in memories if m.get("success", True))
|
|
165
|
+
failure_count = len(memories) - success_count
|
|
166
|
+
|
|
167
|
+
return {
|
|
168
|
+
"total_count": len(memories),
|
|
169
|
+
"success_count": success_count,
|
|
170
|
+
"failure_count": failure_count,
|
|
171
|
+
"last_updated": memories_data.get("last_updated")
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async def save_memories(self, memories: List[Dict], embeddings: Dict[str, np.ndarray]):
|
|
175
|
+
"""批量保存记忆(用于合并后保存)"""
|
|
176
|
+
memories_data = self._load_memories()
|
|
177
|
+
embeddings_data = self._load_embeddings()
|
|
178
|
+
|
|
179
|
+
for mem in memories:
|
|
180
|
+
# 添加记忆
|
|
181
|
+
memories_data["memories"].append(mem)
|
|
182
|
+
|
|
183
|
+
# 添加嵌入
|
|
184
|
+
if mem["memory_id"] in embeddings:
|
|
185
|
+
embedding_vector = embeddings[mem["memory_id"]]
|
|
186
|
+
embeddings_data["embeddings"][mem["memory_id"]] = {
|
|
187
|
+
"query_text": mem.get("query", ""),
|
|
188
|
+
"vector": embedding_vector.tolist() if isinstance(embedding_vector, np.ndarray) else embedding_vector,
|
|
189
|
+
"created_at": mem.get("timestamp", datetime.now().isoformat())
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# 更新元数据
|
|
193
|
+
memories_data["total_count"] = len(memories_data["memories"])
|
|
194
|
+
memories_data["last_updated"] = datetime.now().isoformat()
|
|
195
|
+
embeddings_data["last_updated"] = datetime.now().isoformat()
|
|
196
|
+
|
|
197
|
+
# 保存
|
|
198
|
+
self._save_memories(memories_data)
|
|
199
|
+
self._save_embeddings(embeddings_data)
|
|
200
|
+
|
|
201
|
+
async def get_memory(self, memory_id: str) -> Optional[Dict]:
|
|
202
|
+
"""获取单个记忆(别名)"""
|
|
203
|
+
return await self.get_memory_by_id(memory_id)
|
|
204
|
+
|
|
205
|
+
async def get_embeddings(self, memory_ids: List[str]) -> Dict[str, np.ndarray]:
|
|
206
|
+
"""获取指定记忆的嵌入向量"""
|
|
207
|
+
embeddings_data = self._load_embeddings()
|
|
208
|
+
result = {}
|
|
209
|
+
|
|
210
|
+
for mem_id in memory_ids:
|
|
211
|
+
if mem_id in embeddings_data["embeddings"]:
|
|
212
|
+
result[mem_id] = np.array(embeddings_data["embeddings"][mem_id]["vector"])
|
|
213
|
+
|
|
214
|
+
return result
|
|
215
|
+
|
|
216
|
+
async def archive_memories(self, memories: List[Dict]):
|
|
217
|
+
"""归档记忆到 archived_memories.json"""
|
|
218
|
+
# 加载或创建归档文件
|
|
219
|
+
if self.archived_path.exists():
|
|
220
|
+
with self._lock:
|
|
221
|
+
with open(self.archived_path, 'r', encoding='utf-8') as f:
|
|
222
|
+
archived_data = json.load(f)
|
|
223
|
+
else:
|
|
224
|
+
archived_data = {
|
|
225
|
+
"version": "1.0",
|
|
226
|
+
"description": "已归档的原始经验,不参与检索但可追溯",
|
|
227
|
+
"memories": []
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
# 添加新归档
|
|
231
|
+
archived_data["memories"].extend(memories)
|
|
232
|
+
archived_data["last_updated"] = datetime.now().isoformat()
|
|
233
|
+
|
|
234
|
+
# 保存
|
|
235
|
+
with self._lock:
|
|
236
|
+
with open(self.archived_path, 'w', encoding='utf-8') as f:
|
|
237
|
+
json.dump(archived_data, f, ensure_ascii=False, indent=2)
|
|
238
|
+
|
|
239
|
+
async def get_archived_memory(self, memory_id: str) -> Optional[Dict]:
|
|
240
|
+
"""获取已归档的记忆"""
|
|
241
|
+
if not self.archived_path.exists():
|
|
242
|
+
return None
|
|
243
|
+
|
|
244
|
+
with self._lock:
|
|
245
|
+
with open(self.archived_path, 'r', encoding='utf-8') as f:
|
|
246
|
+
archived_data = json.load(f)
|
|
247
|
+
|
|
248
|
+
for mem in archived_data.get("memories", []):
|
|
249
|
+
if mem["memory_id"] == memory_id:
|
|
250
|
+
return mem
|
|
251
|
+
|
|
252
|
+
return None
|
|
253
|
+
|
|
254
|
+
async def delete_memories(self, memory_ids: List[str], agent_id: Optional[str] = None):
|
|
255
|
+
"""删除记忆(带 agent_id 安全验证)"""
|
|
256
|
+
memories_data = self._load_memories()
|
|
257
|
+
embeddings_data = self._load_embeddings()
|
|
258
|
+
|
|
259
|
+
# 过滤掉要删除的记忆
|
|
260
|
+
deleted_count = 0
|
|
261
|
+
new_memories = []
|
|
262
|
+
|
|
263
|
+
for mem in memories_data["memories"]:
|
|
264
|
+
should_delete = False
|
|
265
|
+
|
|
266
|
+
if mem["memory_id"] in memory_ids:
|
|
267
|
+
# 如果指定了 agent_id,验证权限
|
|
268
|
+
if agent_id is None or mem.get("agent_id") == agent_id:
|
|
269
|
+
should_delete = True
|
|
270
|
+
deleted_count += 1
|
|
271
|
+
|
|
272
|
+
# 同时删除对应的 embedding
|
|
273
|
+
if mem["memory_id"] in embeddings_data["embeddings"]:
|
|
274
|
+
del embeddings_data["embeddings"][mem["memory_id"]]
|
|
275
|
+
|
|
276
|
+
if not should_delete:
|
|
277
|
+
new_memories.append(mem)
|
|
278
|
+
|
|
279
|
+
# 更新数据
|
|
280
|
+
memories_data["memories"] = new_memories
|
|
281
|
+
memories_data["total_count"] = len(new_memories)
|
|
282
|
+
memories_data["last_updated"] = datetime.now().isoformat()
|
|
283
|
+
embeddings_data["last_updated"] = datetime.now().isoformat()
|
|
284
|
+
|
|
285
|
+
# 保存
|
|
286
|
+
self._save_memories(memories_data)
|
|
287
|
+
self._save_embeddings(embeddings_data)
|
|
288
|
+
|
|
289
|
+
return deleted_count
|
|
290
|
+
|
src/storage/base.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""存储后端抽象基类"""
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import List, Dict, Optional
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class StorageBackend(ABC):
|
|
8
|
+
"""存储后端抽���接口"""
|
|
9
|
+
|
|
10
|
+
@abstractmethod
|
|
11
|
+
async def add_memory(self, memory: Dict, embedding: List[float]):
|
|
12
|
+
"""
|
|
13
|
+
添加记忆
|
|
14
|
+
|
|
15
|
+
Args:
|
|
16
|
+
memory: 记忆项字典
|
|
17
|
+
embedding: 嵌入向量
|
|
18
|
+
"""
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
@abstractmethod
|
|
22
|
+
async def get_memory_by_id(self, memory_id: str) -> Optional[Dict]:
|
|
23
|
+
"""
|
|
24
|
+
获取单个记忆
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
memory_id: 记忆 ID
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
记忆项字典,不存在返回 None
|
|
31
|
+
"""
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
async def get_all_memories(self, agent_id: str = None) -> List[Dict]:
|
|
36
|
+
"""
|
|
37
|
+
获取所有记忆
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
agent_id: Agent ID,用于过滤。None 表示获取所有记忆
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
记忆项列表
|
|
44
|
+
"""
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
@abstractmethod
|
|
48
|
+
async def get_all_embeddings(self, agent_id: str = None) -> Dict[str, np.ndarray]:
|
|
49
|
+
"""
|
|
50
|
+
获取所有嵌入向量
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
agent_id: Agent ID,用于过滤。None 表示获取所有嵌入
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
{memory_id: embedding_vector} 字典
|
|
57
|
+
"""
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
@abstractmethod
|
|
61
|
+
async def update_retrieval_stats(self, memory_id: str, timestamp: str):
|
|
62
|
+
"""
|
|
63
|
+
更新检索统计
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
memory_id: 记忆 ID
|
|
67
|
+
timestamp: 检索时间戳
|
|
68
|
+
"""
|
|
69
|
+
pass
|
|
70
|
+
|
|
71
|
+
@abstractmethod
|
|
72
|
+
async def get_stats(self) -> Dict:
|
|
73
|
+
"""
|
|
74
|
+
获取统计信息
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
统计信息字典
|
|
78
|
+
"""
|
|
79
|
+
pass
|
|
80
|
+
|
|
81
|
+
@abstractmethod
|
|
82
|
+
async def save_memories(self, memories: List[Dict], embeddings: Dict[str, np.ndarray]):
|
|
83
|
+
"""
|
|
84
|
+
批量保存记忆(用于合并后保存)
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
memories: 记忆项列表
|
|
88
|
+
embeddings: {memory_id: embedding_vector} 字典
|
|
89
|
+
"""
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
@abstractmethod
|
|
93
|
+
async def get_memory(self, memory_id: str) -> Optional[Dict]:
|
|
94
|
+
"""
|
|
95
|
+
获取单个记忆(别名,与 get_memory_by_id 相同)
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
memory_id: 记忆 ID
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
记忆项字典,不存在返回 None
|
|
102
|
+
"""
|
|
103
|
+
pass
|
|
104
|
+
|
|
105
|
+
@abstractmethod
|
|
106
|
+
async def get_embeddings(self, memory_ids: List[str]) -> Dict[str, np.ndarray]:
|
|
107
|
+
"""
|
|
108
|
+
获取指定记忆的嵌入向量
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
memory_ids: 记忆 ID 列表
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
{memory_id: embedding_vector} 字典
|
|
115
|
+
"""
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
@abstractmethod
|
|
119
|
+
async def archive_memories(self, memories: List[Dict]):
|
|
120
|
+
"""
|
|
121
|
+
归档记忆到 archived_memories.json
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
memories: 要归档的记忆项列表(包含 archived=True 等字段)
|
|
125
|
+
"""
|
|
126
|
+
pass
|
|
127
|
+
|
|
128
|
+
@abstractmethod
|
|
129
|
+
async def get_archived_memory(self, memory_id: str) -> Optional[Dict]:
|
|
130
|
+
"""
|
|
131
|
+
获取已归档的记忆
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
memory_id: 记忆 ID
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
归档的记忆项,不存在返回 None
|
|
138
|
+
"""
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
@abstractmethod
|
|
142
|
+
async def delete_memories(self, memory_ids: List[str], agent_id: Optional[str] = None):
|
|
143
|
+
"""
|
|
144
|
+
删除记忆
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
memory_ids: 要删除的记忆 ID 列表
|
|
148
|
+
agent_id: Agent ID,用于安全验证(只能删除该 agent 的记忆)
|
|
149
|
+
"""
|
|
150
|
+
pass
|