mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
133 lines
4.6 KiB
Python
133 lines
4.6 KiB
Python
"""Router for knowledge graph operations."""
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from loguru import logger
|
|
|
|
from basic_memory.deps import (
|
|
EntityServiceDep,
|
|
KnowledgeServiceDep,
|
|
)
|
|
from basic_memory.schemas import (
|
|
CreateEntityRequest,
|
|
EntityListResponse,
|
|
SearchNodesRequest,
|
|
SearchNodesResponse,
|
|
CreateRelationsRequest,
|
|
EntityResponse,
|
|
AddObservationsRequest,
|
|
OpenNodesRequest,
|
|
DeleteEntitiesResponse,
|
|
DeleteObservationsRequest,
|
|
DeleteRelationsRequest,
|
|
DeleteEntitiesRequest,
|
|
)
|
|
from basic_memory.schemas.base import PathId
|
|
from basic_memory.services.exceptions import EntityNotFoundError
|
|
|
|
router = APIRouter(prefix="/knowledge", tags=["knowledge"])
|
|
|
|
## Create endpoints
|
|
|
|
|
|
@router.post("/entities", response_model=EntityListResponse)
|
|
async def create_entities(
|
|
data: CreateEntityRequest, knowledge_service: KnowledgeServiceDep
|
|
) -> EntityListResponse:
|
|
"""Create new entities in the knowledge graph."""
|
|
entities = await knowledge_service.create_entities(data.entities)
|
|
return EntityListResponse(
|
|
entities=[EntityResponse.model_validate(entity) for entity in entities]
|
|
)
|
|
|
|
|
|
@router.post("/relations", response_model=EntityListResponse)
|
|
async def create_relations(
|
|
data: CreateRelationsRequest, knowledge_service: KnowledgeServiceDep
|
|
) -> EntityListResponse:
|
|
"""Create relations between entities."""
|
|
updated_entities = await knowledge_service.create_relations(data.relations)
|
|
return EntityListResponse(
|
|
entities=[EntityResponse.model_validate(entity) for entity in updated_entities]
|
|
)
|
|
|
|
|
|
@router.post("/observations", response_model=EntityResponse)
|
|
async def add_observations(
|
|
data: AddObservationsRequest, knowledge_service: KnowledgeServiceDep
|
|
) -> EntityResponse:
|
|
"""Add observations to an entity."""
|
|
logger.debug(f"Adding observations to entity: {data.entity_id}")
|
|
updated_entity = await knowledge_service.add_observations(
|
|
data.entity_id, data.observations, data.context
|
|
)
|
|
return EntityResponse.model_validate(updated_entity)
|
|
|
|
|
|
## Read endpoints
|
|
|
|
|
|
@router.get("/entities/{path_id:path}", response_model=EntityResponse)
|
|
async def get_entity(path_id: PathId, entity_service: EntityServiceDep) -> EntityResponse:
|
|
"""Get a specific entity by ID."""
|
|
try:
|
|
entity = await entity_service.get_by_path_id(path_id)
|
|
return EntityResponse.model_validate(entity)
|
|
except EntityNotFoundError:
|
|
raise HTTPException(status_code=404, detail=f"Entity with {path_id} not found")
|
|
|
|
|
|
@router.post("/search", response_model=SearchNodesResponse)
|
|
async def search_nodes(
|
|
data: SearchNodesRequest, entity_service: EntityServiceDep
|
|
) -> SearchNodesResponse:
|
|
"""Search for entities in the knowledge graph."""
|
|
logger.debug(f"Searching nodes with query: {data.query}")
|
|
matches = await entity_service.search(data.query)
|
|
logger.debug(f"Found {len(matches)} matches for '{data.query}'")
|
|
|
|
return SearchNodesResponse(
|
|
matches=[EntityResponse.model_validate(entity) for entity in matches], query=data.query
|
|
)
|
|
|
|
|
|
@router.post("/nodes", response_model=EntityListResponse)
|
|
async def open_nodes(data: OpenNodesRequest, entity_service: EntityServiceDep) -> EntityListResponse:
|
|
"""Open specific nodes by their names."""
|
|
entities = await entity_service.open_nodes(data.entity_ids)
|
|
return EntityListResponse(
|
|
entities=[EntityResponse.model_validate(entity) for entity in entities]
|
|
)
|
|
|
|
|
|
## Delete endpoints
|
|
|
|
|
|
@router.post("/entities/delete", response_model=DeleteEntitiesResponse)
|
|
async def delete_entity(
|
|
data: DeleteEntitiesRequest, knowledge_service: KnowledgeServiceDep
|
|
) -> DeleteEntitiesResponse:
|
|
"""Delete a specific entity by PathId."""
|
|
deleted = await knowledge_service.delete_entities(data.entity_ids)
|
|
return DeleteEntitiesResponse(deleted=deleted)
|
|
|
|
|
|
@router.post("/observations/delete", response_model=EntityResponse)
|
|
async def delete_observations(
|
|
data: DeleteObservationsRequest, knowledge_service: KnowledgeServiceDep
|
|
) -> EntityResponse:
|
|
"""Delete observations from an entity."""
|
|
path_id = data.entity_id
|
|
updated_entity = await knowledge_service.delete_observations(path_id, data.deletions)
|
|
return EntityResponse.model_validate(updated_entity)
|
|
|
|
|
|
@router.post("/relations/delete", response_model=EntityListResponse)
|
|
async def delete_relations(
|
|
data: DeleteRelationsRequest, knowledge_service: KnowledgeServiceDep
|
|
) -> EntityListResponse:
|
|
"""Delete relations between entities."""
|
|
updated_entities = await knowledge_service.delete_relations(data.relations)
|
|
return EntityListResponse(
|
|
entities=[EntityResponse.model_validate(entity) for entity in updated_entities]
|
|
)
|