diff --git a/src/memory/README.md b/src/memory/README.md index 3fd59bbd79..d9a22dbc03 100644 --- a/src/memory/README.md +++ b/src/memory/README.md @@ -108,6 +108,18 @@ Example: - No input required - Returns complete graph structure with all entities and relations +- **read_graph_summary** + - Read a summary of the knowledge graph which includes a summary of each entity and all relations. + - No input required + - Returns: + - Entity summaries with: + - `name` (string): Entity name + - `entityType` (string): Entity type + - `observationCount` (number): Total number of observations + - `lastObservation` (string, optional): The most recent observation for the entity + - Complete relations array (unchanged from full graph) + - Use this to get an overview of the entire graph, then use `open_nodes` to get full details for specific entities + - **search_nodes** - Search for nodes based on query - Input: `query` (string) diff --git a/src/memory/index.ts b/src/memory/index.ts index 982c617be9..b57c74da3c 100644 --- a/src/memory/index.ts +++ b/src/memory/index.ts @@ -38,6 +38,18 @@ interface KnowledgeGraph { relations: Relation[]; } +interface EntitySummary { + name: string; + entityType: string; + observationCount: number; + lastObservation?: string; +} + +interface KnowledgeGraphSummary { + entities: EntitySummary[]; + relations: Relation[]; +} + // The KnowledgeGraphManager class contains all operations to interact with the knowledge graph class KnowledgeGraphManager { private async loadGraph(): Promise { @@ -143,6 +155,32 @@ class KnowledgeGraphManager { return this.loadGraph(); } + async readGraphSummary(): Promise { + const graph = await this.loadGraph(); + + // Create entity summaries without full observation arrays + const entitySummaries = graph.entities.map(entity => { + const observationCount = entity.observations.length; + let lastObservation: string | undefined; + + if (observationCount > 0) { + lastObservation = entity.observations[observationCount - 1]; + } + + return { + name: entity.name, + entityType: entity.entityType, + observationCount, + lastObservation + }; + }); + + return { + entities: entitySummaries, + relations: graph.relations // Relations are already lightweight, include them all + }; + } + // Very basic search function async searchNodes(query: string): Promise { const graph = await this.loadGraph(); @@ -365,6 +403,15 @@ server.setRequestHandler(ListToolsRequestSchema, async () => { additionalProperties: false, }, }, + { + name: "read_graph_summary", + description: "Read the knowledge graph summary. Returns all entity names, types, observation counts, and most recent observations without loading full observation arrays. Use open_nodes to get complete details for specific entities.", + inputSchema: { + type: "object", + properties: {}, + additionalProperties: false, + }, + }, { name: "search_nodes", description: "Search for nodes in the knowledge graph based on a query", @@ -404,6 +451,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => { return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.readGraph(), null, 2) }] }; } + if (name === "read_graph_summary") { + return { content: [{ type: "text", text: JSON.stringify(await knowledgeGraphManager.readGraphSummary(), null, 2) }] }; + } + if (!args) { throw new Error(`No arguments provided for tool: ${name}`); }