|
79 | 79 | from infra_layer.adapters.out.search.repository.episodic_memory_es_repository import ( |
80 | 80 | EpisodicMemoryEsRepository, |
81 | 81 | ) |
| 82 | +from infra_layer.adapters.out.search.repository.event_log_es_repository import ( |
| 83 | + EventLogEsRepository, |
| 84 | +) |
| 85 | +from infra_layer.adapters.out.search.repository.event_log_milvus_repository import ( |
| 86 | + EventLogMilvusRepository, |
| 87 | +) |
82 | 88 | from biz_layer.mem_sync import MemorySyncService |
83 | 89 | from core.context.context import get_current_app_info |
84 | 90 |
|
@@ -1122,6 +1128,19 @@ async def save_memory_docs( |
1122 | 1128 | saved_episodic: List[Any] = [] |
1123 | 1129 |
|
1124 | 1130 | for doc in episodic_docs: |
| 1131 | + # Deduplicate: remove any existing records from the same source MemCell |
| 1132 | + # for this specific user before inserting the new one. |
| 1133 | + # Key is (parent_id, user_id) because one MemCell produces one episode |
| 1134 | + # per participant (personal) plus one group episode (user_id=None/""). |
| 1135 | + parent_id = getattr(doc, "parent_id", None) |
| 1136 | + user_id = getattr(doc, "user_id", None) |
| 1137 | + if parent_id: |
| 1138 | + await asyncio.gather( |
| 1139 | + episodic_repo.delete_by_parent_id(parent_id, user_id=user_id), |
| 1140 | + episodic_es_repo.delete_by_parent_id(parent_id, user_id=user_id), |
| 1141 | + episodic_milvus_repo.delete_by_parent_id(parent_id, user_id=user_id), |
| 1142 | + ) |
| 1143 | + |
1125 | 1144 | saved_doc = await episodic_repo.append_episodic_memory(doc) |
1126 | 1145 | saved_episodic.append(saved_doc) |
1127 | 1146 |
|
@@ -1158,6 +1177,24 @@ async def save_memory_docs( |
1158 | 1177 | event_log_docs = grouped_docs.get(MemoryType.EVENT_LOG, []) |
1159 | 1178 | if event_log_docs: |
1160 | 1179 | event_log_repo = get_bean_by_type(EventLogRecordRawRepository) |
| 1180 | + event_log_es_repo = get_bean_by_type(EventLogEsRepository) |
| 1181 | + event_log_milvus_repo = get_bean_by_type(EventLogMilvusRepository) |
| 1182 | + |
| 1183 | + # Deduplicate: collect unique (parent_id, user_id) pairs and delete old records |
| 1184 | + # before batch-inserting the new ones. |
| 1185 | + seen_parent_keys: set = set() |
| 1186 | + for doc in event_log_docs: |
| 1187 | + parent_id = getattr(doc, "parent_id", None) |
| 1188 | + user_id = getattr(doc, "user_id", None) |
| 1189 | + key = (parent_id, user_id) |
| 1190 | + if parent_id and key not in seen_parent_keys: |
| 1191 | + seen_parent_keys.add(key) |
| 1192 | + await asyncio.gather( |
| 1193 | + event_log_repo.delete_by_parent_id(parent_id), |
| 1194 | + event_log_es_repo.delete_by_parent_id(parent_id, user_id=user_id), |
| 1195 | + event_log_milvus_repo.delete_by_parent_id(parent_id), |
| 1196 | + ) |
| 1197 | + |
1161 | 1198 | saved_event_logs = await event_log_repo.create_batch(event_log_docs) |
1162 | 1199 | saved_result[MemoryType.EVENT_LOG] = saved_event_logs |
1163 | 1200 |
|
|
0 commit comments