diff --git a/src/basic_memory/markdown/knowledge_writer.py b/src/basic_memory/markdown/knowledge_writer.py index 0f492b8c..64505ac4 100644 --- a/src/basic_memory/markdown/knowledge_writer.py +++ b/src/basic_memory/markdown/knowledge_writer.py @@ -60,7 +60,7 @@ class KnowledgeWriter: # This prevents duplicate titles when raw content already has a title if not (entity.observations or entity.outgoing_relations): sections.extend([ - f"# {entity.name}", + f"# {entity.title}", "", # Empty line after title ]) @@ -88,7 +88,7 @@ class KnowledgeWriter: ]) for rel in entity.outgoing_relations: - line = f"- {rel.relation_type} [[{rel.to_entity.name}]]" + line = f"- {rel.relation_type} [[{rel.to_entity.title}]]" if rel.context: line += f" ({rel.context})" sections.append(line) @@ -96,4 +96,4 @@ class KnowledgeWriter: # Return joined sections, ensure content isn't empty content = "\n".join(sections).strip() - return content if content else f"# {entity.name}" + return content if content else f"# {entity.title}" diff --git a/src/basic_memory/models/knowledge.py b/src/basic_memory/models/knowledge.py index e542879b..8855cfe1 100644 --- a/src/basic_memory/models/knowledge.py +++ b/src/basic_memory/models/knowledge.py @@ -42,7 +42,7 @@ class Entity(Base): # Core identity id: Mapped[int] = mapped_column(Integer, primary_key=True) - name: Mapped[str] = mapped_column(String) + title: Mapped[str] = mapped_column(String) entity_type: Mapped[str] = mapped_column(String) entity_metadata: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True) content_type: Mapped[str] = mapped_column(String) @@ -85,7 +85,7 @@ class Entity(Base): return self.incoming_relations + self.outgoing_relations def __repr__(self) -> str: - return f"Entity(id={self.id}, name='{self.name}', type='{self.entity_type}', summary='{self.summary}')" + return f"Entity(id={self.id}, name='{self.title}', type='{self.entity_type}', summary='{self.summary}')" class ObservationCategory(str, Enum): diff --git a/src/basic_memory/repository/entity_repository.py b/src/basic_memory/repository/entity_repository.py index a9aa85ff..35bd1b85 100644 --- a/src/basic_memory/repository/entity_repository.py +++ b/src/basic_memory/repository/entity_repository.py @@ -81,7 +81,7 @@ class EntityRepository(Repository[Entity]): self.select() .where( or_( - Entity.name.ilike(search_term), + Entity.title.ilike(search_term), Entity.entity_type.ilike(search_term), Entity.summary.ilike(search_term), Entity.observations.any(Observation.content.ilike(search_term)), diff --git a/src/basic_memory/services/activity_service.py b/src/basic_memory/services/activity_service.py index 32464e0e..40984157 100644 --- a/src/basic_memory/services/activity_service.py +++ b/src/basic_memory/services/activity_service.py @@ -96,7 +96,7 @@ class ActivityService: change_type=change_type, timestamp=updated_at, path_id=entity.path_id, - summary=f"{change_type.value.title()} entity: {entity.name}", + summary=f"{change_type.value.title()} entity: {entity.title}", content=entity.summary ) ) diff --git a/src/basic_memory/services/search_service.py b/src/basic_memory/services/search_service.py index d5a9dd98..79fdb715 100644 --- a/src/basic_memory/services/search_service.py +++ b/src/basic_memory/services/search_service.py @@ -54,7 +54,7 @@ class SearchService: # Build searchable content content = "\n".join( [ - entity.name, + entity.title, entity.summary or "", # Add observations *[f"{obs.category}: {obs.content}" for obs in entity.observations], diff --git a/src/basic_memory/sync/entity_sync_service.py b/src/basic_memory/sync/entity_sync_service.py index 76f4f84c..ce2286b6 100644 --- a/src/basic_memory/sync/entity_sync_service.py +++ b/src/basic_memory/sync/entity_sync_service.py @@ -23,7 +23,7 @@ def entity_model_from_markdown(file_path: str, markdown: EntityMarkdown) -> Enti return obs.category model = EntityModel( - name=markdown.frontmatter.title, + title=markdown.frontmatter.title, entity_type=markdown.frontmatter.type, path_id=markdown.frontmatter.id, file_path=file_path, @@ -82,7 +82,7 @@ class EntitySyncService: raise EntityNotFoundError(f"Entity not found: {path_id}") # Update fields from markdown - db_entity.name = markdown.frontmatter.title + db_entity.title = markdown.frontmatter.title db_entity.entity_type = markdown.frontmatter.type db_entity.summary = markdown.content.content @@ -106,7 +106,7 @@ class EntitySyncService: return await self.entity_repository.update( db_entity.id, { - "name": db_entity.name, + "name": db_entity.title, "entity_type": db_entity.entity_type, "summary": db_entity.summary, # Mark as incomplete diff --git a/tests/repository/test_entity_repository.py b/tests/repository/test_entity_repository.py index 1231c83c..12912d46 100644 --- a/tests/repository/test_entity_repository.py +++ b/tests/repository/test_entity_repository.py @@ -68,7 +68,7 @@ async def test_create_entity(entity_repository: EntityRepository): # Verify returned object assert entity.id is not None - assert entity.name == "Test" + assert entity.title == "Test" assert entity.summary == "Test description" assert isinstance(entity.created_at, datetime) assert isinstance(entity.updated_at, datetime) @@ -78,7 +78,7 @@ async def test_create_entity(entity_repository: EntityRepository): assert found is not None assert found.id is not None assert found.id == entity.id - assert found.name == entity.name + assert found.title == entity.title assert found.summary == entity.summary # assert relations are eagerly loaded @@ -117,7 +117,7 @@ async def test_create_all(entity_repository: EntityRepository): assert found is not None assert found.id is not None assert found.id == entity.id - assert found.name == entity.name + assert found.title == entity.title assert found.summary == entity.summary # assert relations are eagerly loaded @@ -152,7 +152,7 @@ async def test_find_by_id(entity_repository: EntityRepository, sample_entity: En found = await entity_repository.find_by_id(sample_entity.id) assert found is not None assert found.id == sample_entity.id - assert found.name == sample_entity.name + assert found.title == sample_entity.title # Verify against direct database query async with db.scoped_session(entity_repository.session_maker) as session: @@ -160,7 +160,7 @@ async def test_find_by_id(entity_repository: EntityRepository, sample_entity: En result = await session.execute(stmt) db_entity = result.scalar_one() assert db_entity.id == found.id - assert db_entity.name == found.name + assert db_entity.title == found.title assert db_entity.summary == found.summary @@ -172,7 +172,7 @@ async def test_update_entity(entity_repository: EntityRepository, sample_entity: ) assert updated is not None assert updated.summary == "Updated description" - assert updated.name == sample_entity.name # Other fields unchanged + assert updated.title == sample_entity.title # Other fields unchanged # Verify in database async with db.scoped_session(entity_repository.session_maker) as session: @@ -180,7 +180,7 @@ async def test_update_entity(entity_repository: EntityRepository, sample_entity: result = await session.execute(stmt) db_entity = result.scalar_one() assert db_entity.summary == "Updated description" - assert db_entity.name == sample_entity.name + assert db_entity.title == sample_entity.title @pytest.mark.asyncio @@ -314,21 +314,21 @@ async def test_find_by_path_ids(entity_repository: EntityRepository, test_entiti path_ids = [e.path_id for e in test_entities] found = await entity_repository.find_by_path_ids(path_ids) assert len(found) == 3 - names = {e.name for e in found} + names = {e.title for e in found} assert names == {"entity1", "entity2", "entity3"} # Test finding subset of entities - path_ids = [e.path_id for e in test_entities if e.name != "entity2"] + path_ids = [e.path_id for e in test_entities if e.title != "entity2"] found = await entity_repository.find_by_path_ids(path_ids) assert len(found) == 2 - names = {e.name for e in found} + names = {e.title for e in found} assert names == {"entity1", "entity3"} # Test with non-existent entities path_ids = ["type1/entity1", "type3/nonexistent"] found = await entity_repository.find_by_path_ids(path_ids) assert len(found) == 1 - assert found[0].name == "entity1" + assert found[0].title == "entity1" # Test empty input found = await entity_repository.find_by_path_ids([]) @@ -339,14 +339,14 @@ async def test_find_by_path_ids(entity_repository: EntityRepository, test_entiti async def test_delete_by_path_ids(entity_repository: EntityRepository, test_entities): """Test deleting entities by type/name pairs.""" # Test deleting multiple entities - path_ids = [e.path_id for e in test_entities if e.name != "entity3"] + path_ids = [e.path_id for e in test_entities if e.title != "entity3"] deleted_count = await entity_repository.delete_by_path_ids(path_ids) assert deleted_count == 2 # Verify deletions remaining = await entity_repository.find_all() assert len(remaining) == 1 - assert remaining[0].name == "entity3" + assert remaining[0].title == "entity3" # Test deleting non-existent entities path__ids = ["type3/nonexistent"] @@ -433,7 +433,7 @@ async def test_list_entities_with_related(entity_repository: EntityRepository, s # Test 1: List without related entities services = await entity_repository.list_entities(entity_type="test", include_related=False) assert len(services) == 2 - service_names = {s.name for s in services} + service_names = {s.title for s in services} assert service_names == {"service_config", "db_service"} # Test 2: List services with related entities @@ -442,10 +442,10 @@ async def test_list_entities_with_related(entity_repository: EntityRepository, s ) assert len(services_and_related) == 3 # Should include both services and the config - entity_names = {e.name for e in services_and_related} + entity_names = {e.title for e in services_and_related} assert entity_names == {"core_service", "db_service", "service_config"} # Test 3: Verify relations are loaded - core_service = next(e for e in services_and_related if e.name == "core_service") + core_service = next(e for e in services_and_related if e.title == "core_service") assert len(core_service.outgoing_relations) > 0 # Has incoming relation from config assert len(core_service.incoming_relations) > 0 # Has outgoing relation to db diff --git a/tests/repository/test_repository.py b/tests/repository/test_repository.py index e1a56fb5..851c294b 100644 --- a/tests/repository/test_repository.py +++ b/tests/repository/test_repository.py @@ -41,7 +41,7 @@ async def test_add(repository): # Verify we can find in db found = await repository.find_by_id("test_add") assert found is not None - assert found.name == "Test Add" + assert found.title == "Test Add" @pytest.mark.asyncio @@ -54,7 +54,7 @@ async def test_add_all(repository): # Verify we can find them in db found = await repository.find_by_id("test_0") assert found is not None - assert found.name == "Test 0" + assert found.title == "Test 0" @pytest.mark.asyncio @@ -69,7 +69,7 @@ async def test_bulk_create(repository): # Verify we can find them in db found = await repository.find_by_id("test_0") assert found is not None - assert found.name == "Test 0" + assert found.title == "Test 0" @pytest.mark.asyncio diff --git a/tests/services/test_entity_service.py b/tests/services/test_entity_service.py index 0f4f2555..23f21dc1 100644 --- a/tests/services/test_entity_service.py +++ b/tests/services/test_entity_service.py @@ -31,7 +31,7 @@ async def test_create_entity(entity_service: EntityService, file_service: FileSe # Assert Entity assert isinstance(entity, EntityModel) - assert entity.name == "TestEntity" + assert entity.title == "TestEntity" assert entity.path_id == entity_data.path_id assert entity.file_path == entity_data.file_path assert entity.entity_type == "test" @@ -43,7 +43,7 @@ async def test_create_entity(entity_service: EntityService, file_service: FileSe # Verify we can retrieve it using path_id retrieved = await entity_service.get_by_path_id(entity_data.path_id) assert retrieved.summary == "A test entity description" - assert retrieved.name == "TestEntity" + assert retrieved.title == "TestEntity" assert retrieved.entity_type == "test" assert retrieved.summary == "A test entity description" assert retrieved.created_at is not None @@ -88,7 +88,7 @@ async def test_create_entities(entity_service: EntityService, file_service: File assert len(entities) == 2 entity1 = entities[0] assert isinstance(entity1, EntityModel) - assert entity1.name == "TestEntity1" + assert entity1.title == "TestEntity1" assert entity1.entity_type == "test" assert entity1.summary == "A test entity description" assert entity1.created_at is not None @@ -97,7 +97,7 @@ async def test_create_entities(entity_service: EntityService, file_service: File entity2 = entities[1] assert isinstance(entity1, EntityModel) - assert entity2.name == "TestEntity2" + assert entity2.title == "TestEntity2" assert entity2.entity_type == "test" assert entity2.summary == "A test entity description" assert entity2.created_at is not None @@ -180,7 +180,7 @@ async def test_get_entity_success(entity_service: EntityService): retrieved = await entity_service.get_by_path_id(entity_data.path_id) assert isinstance(retrieved, EntityModel) - assert retrieved.name == "TestEntity" + assert retrieved.title == "TestEntity" assert retrieved.entity_type == "test" assert retrieved.summary == "Test description" @@ -226,7 +226,7 @@ async def test_create_entity_with_special_chars(entity_service: EntityService): ) entity = await entity_service.create_entity(entity_data) - assert entity.name == name + assert entity.title == name assert entity.summary == description # Verify after retrieval using path_id @@ -275,7 +275,7 @@ async def test_open_nodes_by_path_ids(entity_service: EntityService): found = await entity_service.open_nodes(path_ids) assert len(found) == 2 - names = {e.name for e in found} + names = {e.title for e in found} assert names == {"Entity1", "Entity2"} @@ -301,7 +301,7 @@ async def test_open_nodes_some_not_found(entity_service: EntityService): found = await entity_service.open_nodes(path_ids) assert len(found) == 1 - assert found[0].name == "Entity1" + assert found[0].title == "Entity1" async def test_delete_entities_by_path_ids(entity_service: EntityService): @@ -439,7 +439,7 @@ async def test_update_entity_name(entity_service: EntityService, file_service: F updated = await entity_service.update_entity(entity.path_id, name="new-name") # Verify name was updated in DB - assert updated.name == "new-name" + assert updated.title == "new-name" # Verify frontmatter was updated in file file_path = file_service.get_entity_path(updated) diff --git a/tests/services/test_relation_service.py b/tests/services/test_relation_service.py index 1e119e19..90e33b88 100644 --- a/tests/services/test_relation_service.py +++ b/tests/services/test_relation_service.py @@ -90,8 +90,8 @@ async def test_create_relations( content, _ = await file_service.read_file(file_path) # verify relation format - assert f"- type_0 [[{entity2.name}]] (context_0)" in content - assert f"- type_1 [[{entity2.name}]] (context_1)" in content + assert f"- type_0 [[{entity2.title}]] (context_0)" in content + assert f"- type_1 [[{entity2.title}]] (context_1)" in content # Verify other entity file is not updated found = await entity_service.get_by_path_id(entity2.path_id) diff --git a/tests/sync/test_knowledge_sync_service.py b/tests/sync/test_knowledge_sync_service.py index bd62a032..952119bb 100644 --- a/tests/sync/test_knowledge_sync_service.py +++ b/tests/sync/test_knowledge_sync_service.py @@ -62,7 +62,7 @@ async def test_create_entity_without_relations( entity = await knowledge_sync_service.create_entity_from_markdown("test.md", test_markdown) # Check basic fields - assert entity.name == "Test Entity" + assert entity.title == "Test Entity" assert entity.entity_type == "knowledge" assert entity.path_id == "concept/test_entity" assert entity.summary == "A test entity description" @@ -98,7 +98,7 @@ async def test_update_entity_without_relations( ) # Check fields updated - assert updated.name == "Updated Title" + assert updated.title == "Updated Title" assert updated.summary == "Updated description" assert len(updated.observations) == 1 assert updated.observations[0].content == "Updated observation"