From 31e81c90165b3dd7d42efbd4e572f5a0e16440b7 Mon Sep 17 00:00:00 2001 From: phernandez Date: Mon, 30 Dec 2024 23:05:41 -0600 Subject: [PATCH] fix circular imports --- src/basic_memory/mcp/tools/activity.py | 21 +++++++++----------- src/basic_memory/mcp/tools/discovery.py | 26 +++++++++++-------------- src/basic_memory/mcp/tools/documents.py | 12 ++++++------ src/basic_memory/mcp/tools/search.py | 23 ++++++++++++---------- 4 files changed, 39 insertions(+), 43 deletions(-) diff --git a/src/basic_memory/mcp/tools/activity.py b/src/basic_memory/mcp/tools/activity.py index 6b28860c..3b7a54a6 100644 --- a/src/basic_memory/mcp/tools/activity.py +++ b/src/basic_memory/mcp/tools/activity.py @@ -5,44 +5,41 @@ from typing import List, Optional from loguru import logger from basic_memory.mcp.async_client import client -from basic_memory.mcp.server import mcp +from basic_memory.mcp.tools.enhanced import enhanced_tool from basic_memory.schemas.activity import ActivityType, RecentActivity -@mcp.tool() +@enhanced_tool() async def get_recent_activity( timeframe: str = "1d", activity_types: Optional[List[ActivityType]] = None, ) -> RecentActivity: """ Get recent activity across your knowledge base. - + Shows you what has changed recently including: - Document changes - Entity updates - Relation modifications - + You can filter by: - Timeframe (e.g., 1h, 1d, 1w, 1m) - Activity types (document, entity, relation) - + Examples: # Get all activity in last day activity = await get_recent_activity() - + # Get only document changes docs = await get_recent_activity( timeframe="1h", activity_types=[ActivityType.DOCUMENT] ) - + Returns: RecentActivity object with changes and summary """ - logger.debug( - f"Getting recent activity (timeframe={timeframe}, " - f"types={activity_types})" - ) + logger.debug(f"Getting recent activity (timeframe={timeframe}, " f"types={activity_types})") # Build params params = { @@ -53,4 +50,4 @@ async def get_recent_activity( # Get activity response = await client.get("/activity/recent", params=params) - return RecentActivity.model_validate(response.json()) \ No newline at end of file + return RecentActivity.model_validate(response.json()) diff --git a/src/basic_memory/mcp/tools/discovery.py b/src/basic_memory/mcp/tools/discovery.py index c72999a1..abbb732c 100644 --- a/src/basic_memory/mcp/tools/discovery.py +++ b/src/basic_memory/mcp/tools/discovery.py @@ -4,26 +4,26 @@ from typing import List, Optional from loguru import logger +from basic_memory.mcp.tools.enhanced import enhanced_tool from basic_memory.schemas import EntityTypeList, ObservationCategoryList, TypedEntityList from basic_memory.mcp.async_client import client -from basic_memory.mcp.server import mcp -@mcp.tool() +@enhanced_tool() async def get_entity_types() -> List[str]: """List all unique entity types in use across the knowledge graph. - + Examples: types = await get_entity_types() - + # Returns list of strings like: # [ # "technical_component", - # "specification", + # "specification", # "decision", # "feature" # ] - + Returns: List of unique entity type strings used in the knowledge graph """ @@ -33,7 +33,7 @@ async def get_entity_types() -> List[str]: return EntityTypeList.model_validate(response.json()) -@mcp.tool() +@enhanced_tool() async def get_observation_categories() -> List[str]: """List all unique observation categories in use across the knowledge graph. @@ -57,11 +57,9 @@ async def get_observation_categories() -> List[str]: return ObservationCategoryList.model_validate(response.json()) -@mcp.tool() +@enhanced_tool() async def list_by_type( - entity_type: str, - include_related: bool = False, - sort_by: Optional[str] = "updated_at" + entity_type: str, include_related: bool = False, sort_by: Optional[str] = "updated_at" ) -> TypedEntityList: """List all entities of a specific type. @@ -76,12 +74,10 @@ async def list_by_type( ) """ logger.debug(f"Listing entities of type: {entity_type}") - params = { - "include_related": "true" if include_related else "false" - } + params = {"include_related": "true" if include_related else "false"} if sort_by: params["sort_by"] = sort_by url = f"/discovery/entities/{entity_type}" response = await client.get(url, params=params) - return TypedEntityList.model_validate(response.json()) \ No newline at end of file + return TypedEntityList.model_validate(response.json()) diff --git a/src/basic_memory/mcp/tools/documents.py b/src/basic_memory/mcp/tools/documents.py index 6d80ec63..a3d1e38d 100644 --- a/src/basic_memory/mcp/tools/documents.py +++ b/src/basic_memory/mcp/tools/documents.py @@ -2,13 +2,13 @@ from typing import Dict, List +from basic_memory.mcp.tools.enhanced import enhanced_tool from basic_memory.schemas.request import DocumentRequest, DocumentPathId from basic_memory.schemas.response import DocumentResponse, DocumentCreateResponse from basic_memory.mcp.async_client import client -from basic_memory.mcp.server import mcp -@mcp.tool() +@enhanced_tool() async def create_document(request: DocumentRequest) -> DocumentCreateResponse: """Create a new markdown document. @@ -48,7 +48,7 @@ async def create_document(request: DocumentRequest) -> DocumentCreateResponse: return DocumentCreateResponse.model_validate(response.json()) -@mcp.tool() +@enhanced_tool() async def update_document(request: DocumentRequest) -> DocumentResponse: """Update an existing document. @@ -85,7 +85,7 @@ async def update_document(request: DocumentRequest) -> DocumentResponse: return DocumentResponse.model_validate(response.json()) -@mcp.tool() +@enhanced_tool() async def get_document(path: DocumentPathId) -> DocumentResponse: """Get a document by its path. @@ -114,7 +114,7 @@ async def get_document(path: DocumentPathId) -> DocumentResponse: return DocumentResponse.model_validate(response.json()) -@mcp.tool() +@enhanced_tool() async def list_documents() -> List[DocumentCreateResponse]: """List all documents in the system. @@ -145,7 +145,7 @@ async def list_documents() -> List[DocumentCreateResponse]: return [DocumentCreateResponse.model_validate(doc) for doc in response.json()] -@mcp.tool() +@enhanced_tool() async def delete_document(path: DocumentPathId) -> Dict[str, bool]: """Delete a document. diff --git a/src/basic_memory/mcp/tools/search.py b/src/basic_memory/mcp/tools/search.py index 6bd77fb4..194dc37f 100644 --- a/src/basic_memory/mcp/tools/search.py +++ b/src/basic_memory/mcp/tools/search.py @@ -1,16 +1,17 @@ """Search and query tools for Basic Memory MCP server.""" + from typing import Dict +from basic_memory.mcp.tools.enhanced import enhanced_tool from basic_memory.schemas.request import SearchNodesRequest, OpenNodesRequest from basic_memory.schemas.response import SearchNodesResponse, EntityResponse from basic_memory.mcp.async_client import client -from basic_memory.mcp.server import mcp -@mcp.tool() +@enhanced_tool() async def search_nodes(request: SearchNodesRequest) -> SearchNodesResponse: """Search for entities in the knowledge graph. - + Examples: # Find technical implementation details request = SearchNodesRequest( @@ -18,7 +19,7 @@ async def search_nodes(request: SearchNodesRequest) -> SearchNodesResponse: category=ObservationCategory.TECH ) response = await search_nodes(request) - + # Response contains matching entities: # SearchNodesResponse( # matches=[ @@ -50,10 +51,10 @@ async def search_nodes(request: SearchNodesRequest) -> SearchNodesResponse: return SearchNodesResponse.model_validate(response.json()) -@mcp.tool() +@enhanced_tool() async def open_nodes(request: OpenNodesRequest) -> Dict[str, EntityResponse]: """Load multiple entities by their path_ids. - + Examples: # Load related components and their specs request = OpenNodesRequest( @@ -64,14 +65,14 @@ async def open_nodes(request: OpenNodesRequest) -> Dict[str, EntityResponse]: ] ) response = await open_nodes(request) - + # Response maps path_ids to entities: # { # "component/memory_service": EntityResponse(...), # "component/file_service": EntityResponse(...), # "specification/file_format": EntityResponse(...) # } - + # Follow relation chains request = OpenNodesRequest( path_ids=[ @@ -84,5 +85,7 @@ async def open_nodes(request: OpenNodesRequest) -> Dict[str, EntityResponse]: """ url = "/knowledge/nodes" response = await client.post(url, json=request.model_dump()) - return {entity["path_id"]: EntityResponse.model_validate(entity) - for entity in response.json()["entities"]} \ No newline at end of file + return { + entity["path_id"]: EntityResponse.model_validate(entity) + for entity in response.json()["entities"] + }