Skip to main content
Glama
waypoint-builder.test.ts8.8 kB
/** * Waypoint Graph Builder Tests * * Tests for waypoint connection creation system. * Tests cover: * - Finding relevant connections (max 1-3 per memory) * - Connection type classification (causal, associative, temporal, hierarchical) * - Connection strength calculation * - Bidirectional connection creation * - Self-connection prevention */ import { beforeEach, describe, expect, it } from "vitest"; import type { Memory, WaypointGraphConfig } from "../../../graph/types"; import { WaypointGraphBuilder } from "../../../graph/waypoint-builder"; const mockDbManager = { pool: { query: async () => ({ rows: [] }), }, } as any; const mockEmbeddingStorage = { retrieveEmbeddings: async () => ({ episodic: createTestEmbedding(768, 0.1), semantic: createTestEmbedding(768, 0.2), procedural: createTestEmbedding(768, 0.3), emotional: createTestEmbedding(768, 0.4), reflective: createTestEmbedding(768, 0.5), }), vectorSimilaritySearch: async () => [], } as any; // Helper functions function createTestEmbedding(dimension: number, seed: number): number[] { return Array.from({ length: dimension }, (_, i) => Math.sin(seed + i * 0.1)); } function createTestMemory(id: string, content: string): Memory { return { id, userId: "user-1", sessionId: "session-1", content, primarySector: "semantic", metadata: { keywords: [], tags: [], category: "test", context: "test context", importance: 0.5, isAtomic: true, }, createdAt: new Date(), lastAccessed: new Date(), accessCount: 0, strength: 1.0, salience: 0.5, }; } function createTestMemories(count: number): Memory[] { return Array.from({ length: count }, (_, i) => createTestMemory(`mem-${i + 1}`, `Memory content ${i + 1}`) ); } describe("WaypointGraphBuilder - Connection Discovery", () => { let builder: WaypointGraphBuilder; let config: WaypointGraphConfig; beforeEach(() => { config = { similarityThreshold: 0.7, maxLinksPerNode: 3, minLinksPerNode: 1, enableBidirectional: true, }; builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, config); }); it("should find relevant connections with max 1-3 per memory", async () => { const newMemory = createTestMemory("mem-001", "New memory content"); const existingMemories = createTestMemories(10); const result = await builder.createWaypointLinks(newMemory, existingMemories); expect(result.links).toBeDefined(); expect(result.links.length).toBeGreaterThanOrEqual(0); expect(result.links.length).toBeLessThanOrEqual(3); }); it("should only create links above similarity threshold", async () => { const newMemory = createTestMemory("mem-001", "New memory content"); const existingMemories = createTestMemories(10); const result = await builder.createWaypointLinks(newMemory, existingMemories); result.links.forEach((link) => { expect(link.weight).toBeGreaterThanOrEqual(config.similarityThreshold); }); }); it("should handle empty candidate pool", async () => { const newMemory = createTestMemory("mem-001", "First memory"); const existingMemories: Memory[] = []; const result = await builder.createWaypointLinks(newMemory, existingMemories); expect(result.links).toEqual([]); expect(result.skippedCount).toBe(0); }); }); describe("WaypointGraphBuilder - Connection Type Classification", () => { let builder: WaypointGraphBuilder; beforeEach(() => { const config: WaypointGraphConfig = { similarityThreshold: 0.7, maxLinksPerNode: 3, minLinksPerNode: 1, enableBidirectional: true, }; builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, config); }); it("should classify link types", async () => { const source = createTestMemory("mem-001", "Action A causes result B"); const target = createTestMemory("mem-002", "Result B happened because of A"); const linkType = await builder.classifyLinkType(source, target); // Should return a valid LinkType expect(linkType).toBeDefined(); }); }); describe("WaypointGraphBuilder - Connection Weight Calculation", () => { let builder: WaypointGraphBuilder; beforeEach(() => { const config: WaypointGraphConfig = { similarityThreshold: 0.7, maxLinksPerNode: 3, minLinksPerNode: 1, enableBidirectional: true, }; builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, config); }); it("should calculate weight based on embedding similarity", async () => { const source = createTestMemory("mem-001", "Source memory"); const target = createTestMemory("mem-002", "Target memory"); const weight = await builder.calculateLinkWeight(source, target); expect(weight).toBeGreaterThanOrEqual(0); expect(weight).toBeLessThanOrEqual(1); }); }); describe("WaypointGraphBuilder - Bidirectional Connection Creation", () => { let builder: WaypointGraphBuilder; beforeEach(() => { const config: WaypointGraphConfig = { similarityThreshold: 0.7, maxLinksPerNode: 3, minLinksPerNode: 1, enableBidirectional: true, }; builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, config); }); it("should create bidirectional links via createWaypointLinks", async () => { const source = createTestMemory("mem-001", "Source memory"); const target = createTestMemory("mem-002", "Target memory"); const result = await builder.createWaypointLinks(source, [target]); // With bidirectional enabled, links should be created expect(result.links).toBeDefined(); }); }); describe("WaypointGraphBuilder - Self-Connection Prevention", () => { let builder: WaypointGraphBuilder; beforeEach(() => { const config: WaypointGraphConfig = { similarityThreshold: 0.7, maxLinksPerNode: 3, minLinksPerNode: 1, enableBidirectional: true, }; builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, config); }); it("should validate links are not self-referential", async () => { const memory = createTestMemory("mem-001", "Memory"); const isValid = await builder.validateLink(memory.id, memory.id); expect(isValid).toBe(false); }); it("should validate different source and target", async () => { const source = createTestMemory("mem-001", "Source"); const target = createTestMemory("mem-002", "Target"); const isValid = await builder.validateLink(source.id, target.id); expect(isValid).toBe(true); }); }); describe("WaypointGraphBuilder - Configuration", () => { it("should create builder with standard config", () => { const standardConfig: WaypointGraphConfig = { similarityThreshold: 0.7, maxLinksPerNode: 3, minLinksPerNode: 1, enableBidirectional: true, }; const builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, standardConfig); expect(builder).toBeDefined(); }); it("should create builder with custom config", () => { const customConfig: WaypointGraphConfig = { similarityThreshold: 0.8, maxLinksPerNode: 5, minLinksPerNode: 2, enableBidirectional: false, }; const builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, customConfig); expect(builder).toBeDefined(); }); }); describe("WaypointGraphBuilder - Edge Cases", () => { let builder: WaypointGraphBuilder; beforeEach(() => { builder = new WaypointGraphBuilder(mockDbManager, mockEmbeddingStorage, { similarityThreshold: 0.7, maxLinksPerNode: 3, minLinksPerNode: 1, enableBidirectional: true, }); }); it("should handle empty existing memories", async () => { const newMemory = createTestMemory("mem-001", "New memory"); const result = await builder.createWaypointLinks(newMemory, []); expect(result.links).toEqual([]); }); it("should handle single existing memory", async () => { const newMemory = createTestMemory("mem-001", "New memory"); const existingMemories = [createTestMemory("mem-002", "Existing memory")]; const result = await builder.createWaypointLinks(newMemory, existingMemories); expect(result.links.length).toBeLessThanOrEqual(1); }); it("should handle memory with same ID as source", async () => { const memory = createTestMemory("mem-001", "Memory"); const existingMemories = [memory]; // Same memory in existing list const result = await builder.createWaypointLinks(memory, existingMemories); // Should not create self-referential links result.links.forEach((link) => { expect(link.sourceId).not.toBe(link.targetId); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/keyurgolani/ThoughtMcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server