Spaces:
Running
Running
| # backend/memory/semantic_memory.py | |
| # Knowledge graph stored in MongoDB as an adjacency list using two collections: nodes and edges | |
| import uuid | |
| from backend.db.mongodb import MongoDBClient | |
| class SemanticMemory: | |
| def __init__(self, db_path: str = None): | |
| # db_path is ignored now since we use MongoDB | |
| self.nodes = MongoDBClient.get_db().nodes | |
| self.edges = MongoDBClient.get_db().edges | |
| async def _get_or_create_node(self, label: str) -> str: | |
| label = label.lower() | |
| node = await self.nodes.find_one({'label': label}) | |
| if node: | |
| return node['_id'] | |
| node_id = str(uuid.uuid4()) | |
| await self.nodes.insert_one({ | |
| '_id': node_id, | |
| 'label': label, | |
| 'properties': {} | |
| }) | |
| return node_id | |
| async def add_fact(self, subject: str, predicate: str, obj: str, confidence: float = 1.0): | |
| from_id = await self._get_or_create_node(subject) | |
| to_id = await self._get_or_create_node(obj) | |
| predicate = predicate.lower() | |
| # Upsert the edge based on from_id, to_id, and relation | |
| await self.edges.update_one( | |
| { | |
| 'from_id': from_id, | |
| 'to_id': to_id, | |
| 'relation': predicate | |
| }, | |
| { | |
| '$set': {'weight': confidence} | |
| }, | |
| upsert=True | |
| ) | |
| async def query_facts(self, subject: str) -> list[dict]: | |
| subject_lower = subject.lower() | |
| node = await self.nodes.find_one({'label': subject_lower}) | |
| if not node: | |
| return [] | |
| subject_id = node['_id'] | |
| results = [] | |
| # Outgoing edges (where subject is the source) | |
| async for edge in self.edges.find({'from_id': subject_id}): | |
| obj_node = await self.nodes.find_one({'_id': edge['to_id']}) | |
| if obj_node: | |
| results.append({ | |
| "subject": subject_lower, | |
| "predicate": edge['relation'], | |
| "object": obj_node['label'], | |
| "confidence": edge.get('weight', 1.0) | |
| }) | |
| # Incoming edges (where subject is the target) | |
| async for edge in self.edges.find({'to_id': subject_id}): | |
| subj_node = await self.nodes.find_one({'_id': edge['from_id']}) | |
| if subj_node: | |
| results.append({ | |
| "subject": subj_node['label'], | |
| "predicate": edge['relation'], | |
| "object": subject_lower, | |
| "confidence": edge.get('weight', 1.0) | |
| }) | |
| return results | |