mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
rename incoming/outgoing relations on Entity model
This commit is contained in:
@@ -66,7 +66,7 @@ class KnowledgeWriter:
|
||||
)
|
||||
|
||||
# Format outgoing and incoming relations separately
|
||||
if entity.to_relations or entity.from_relations:
|
||||
if entity.incoming_relations or entity.outgoing_relations:
|
||||
sections.extend(
|
||||
[
|
||||
"## Relations",
|
||||
@@ -75,7 +75,7 @@ class KnowledgeWriter:
|
||||
)
|
||||
|
||||
# Outgoing relations (entity is "from")
|
||||
for rel in entity.from_relations:
|
||||
for rel in entity.outgoing_relations:
|
||||
sections.append(f"- {rel.relation_type} [[{rel.to_entity.name}]] ")
|
||||
|
||||
if metadata:
|
||||
|
||||
@@ -60,13 +60,13 @@ class Entity(Base):
|
||||
observations = relationship(
|
||||
"Observation", back_populates="entity", cascade="all, delete-orphan"
|
||||
)
|
||||
from_relations = relationship(
|
||||
outgoing_relations = relationship(
|
||||
"Relation",
|
||||
back_populates="from_entity",
|
||||
foreign_keys="[Relation.from_id]",
|
||||
cascade="all, delete-orphan",
|
||||
)
|
||||
to_relations = relationship(
|
||||
incoming_relations = relationship(
|
||||
"Relation",
|
||||
back_populates="to_entity",
|
||||
foreign_keys="[Relation.to_id]",
|
||||
@@ -76,7 +76,7 @@ class Entity(Base):
|
||||
|
||||
@property
|
||||
def relations(self):
|
||||
return self.to_relations + self.from_relations
|
||||
return self.incoming_relations + self.outgoing_relations
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Entity(id={self.id}, name='{self.name}', type='{self.entity_type}')"
|
||||
@@ -153,8 +153,8 @@ class Relation(Base):
|
||||
)
|
||||
|
||||
# Relationships
|
||||
from_entity = relationship("Entity", foreign_keys=[from_id], back_populates="from_relations")
|
||||
to_entity = relationship("Entity", foreign_keys=[to_id], back_populates="to_relations")
|
||||
from_entity = relationship("Entity", foreign_keys=[from_id], back_populates="outgoing_relations")
|
||||
to_entity = relationship("Entity", foreign_keys=[to_id], back_populates="incoming_relations")
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Relation(id={self.id}, from_id={self.from_id}, to_id={self.to_id}, type='{self.relation_type}')"
|
||||
|
||||
@@ -45,8 +45,8 @@ class EntityRepository(Repository[Entity]):
|
||||
query = query.where(
|
||||
or_(
|
||||
Entity.entity_type == entity_type,
|
||||
Entity.from_relations.any(Relation.to_entity.has(entity_type=entity_type)),
|
||||
Entity.to_relations.any(Relation.from_entity.has(entity_type=entity_type))
|
||||
Entity.outgoing_relations.any(Relation.to_entity.has(entity_type=entity_type)),
|
||||
Entity.incoming_relations.any(Relation.from_entity.has(entity_type=entity_type))
|
||||
)
|
||||
)
|
||||
else:
|
||||
@@ -108,11 +108,11 @@ class EntityRepository(Repository[Entity]):
|
||||
return [
|
||||
selectinload(Entity.observations),
|
||||
# Load from_relations and both entities for each relation
|
||||
selectinload(Entity.from_relations).selectinload(Relation.from_entity),
|
||||
selectinload(Entity.from_relations).selectinload(Relation.to_entity),
|
||||
selectinload(Entity.outgoing_relations).selectinload(Relation.from_entity),
|
||||
selectinload(Entity.outgoing_relations).selectinload(Relation.to_entity),
|
||||
# Load to_relations and both entities for each relation
|
||||
selectinload(Entity.to_relations).selectinload(Relation.from_entity),
|
||||
selectinload(Entity.to_relations).selectinload(Relation.to_entity),
|
||||
selectinload(Entity.incoming_relations).selectinload(Relation.from_entity),
|
||||
selectinload(Entity.incoming_relations).selectinload(Relation.to_entity),
|
||||
]
|
||||
|
||||
async def find_by_path_ids(self, path_ids: List[str]) -> Sequence[Entity]:
|
||||
|
||||
@@ -57,7 +57,7 @@ def test_entity():
|
||||
|
||||
# Create relation from main entity to other
|
||||
relation = Relation(from_entity=entity, to_entity=other_entity, relation_type="relates_to")
|
||||
entity.from_relations = [relation]
|
||||
entity.outgoing_relations = [relation]
|
||||
|
||||
return entity
|
||||
|
||||
|
||||
@@ -525,8 +525,8 @@ async def test_list_entities_with_related(entity_repository: EntityRepository, s
|
||||
|
||||
# Test 3: Verify relations are loaded
|
||||
core_service = next(e for e in services_and_related if e.name == "core_service")
|
||||
assert len(core_service.from_relations) > 0 # Has incoming relation from config
|
||||
assert len(core_service.to_relations) > 0 # Has outgoing relation to db
|
||||
assert len(core_service.outgoing_relations) > 0 # Has incoming relation from config
|
||||
assert len(core_service.incoming_relations) > 0 # Has outgoing relation to db
|
||||
|
||||
# Test 4: List configurations with related
|
||||
configs = await entity_repository.list_entities(
|
||||
|
||||
@@ -163,22 +163,22 @@ modified: 2024-01-01
|
||||
entity_b = await sync_service.knowledge_sync_service.entity_service.get_by_path_id("concept/entity_b")
|
||||
|
||||
# outgoing relations
|
||||
assert len(entity_a.from_relations) == 1
|
||||
assert len(entity_b.from_relations) == 1
|
||||
assert len(entity_a.outgoing_relations) == 1
|
||||
assert len(entity_b.outgoing_relations) == 1
|
||||
|
||||
# incoming relations
|
||||
assert len(entity_a.to_relations) == 1
|
||||
assert len(entity_b.to_relations) == 1
|
||||
assert len(entity_a.incoming_relations) == 1
|
||||
assert len(entity_b.incoming_relations) == 1
|
||||
|
||||
# all relations
|
||||
assert len(entity_a.relations) == 2
|
||||
assert len(entity_b.relations) == 2
|
||||
|
||||
# Verify circular reference works
|
||||
a_relation = entity_a.from_relations[0]
|
||||
a_relation = entity_a.outgoing_relations[0]
|
||||
assert a_relation.to_id == entity_b.id
|
||||
|
||||
b_relation = entity_b.from_relations[0]
|
||||
b_relation = entity_b.outgoing_relations[0]
|
||||
assert b_relation.to_id == entity_a.id
|
||||
|
||||
|
||||
@@ -358,13 +358,13 @@ modified: 2024-01-01
|
||||
entity_b = await sync_service.knowledge_sync_service.entity_service.get_by_path_id("concept/entity_b")
|
||||
entity_c = await sync_service.knowledge_sync_service.entity_service.get_by_path_id("concept/entity_c")
|
||||
|
||||
assert len(entity_a.from_relations) == 2 # Should depend on B and C
|
||||
assert len(entity_a.to_relations) == 1 # C depends on A
|
||||
assert len(entity_a.outgoing_relations) == 2 # Should depend on B and C
|
||||
assert len(entity_a.incoming_relations) == 1 # C depends on A
|
||||
|
||||
|
||||
assert len(entity_b.from_relations) == 1 # Should depend on C
|
||||
assert len(entity_b.to_relations) == 1 # A depends on B
|
||||
assert len(entity_b.outgoing_relations) == 1 # Should depend on C
|
||||
assert len(entity_b.incoming_relations) == 1 # A depends on B
|
||||
|
||||
|
||||
assert len(entity_c.from_relations) == 1 # Should depend on A
|
||||
assert len(entity_c.to_relations) == 2 # A and B depend on C
|
||||
assert len(entity_c.outgoing_relations) == 1 # Should depend on A
|
||||
assert len(entity_c.incoming_relations) == 2 # A and B depend on C
|
||||
Reference in New Issue
Block a user