Skip to main content
Glama

DevFlow MCP

by Takin-Profit
sqlite-storage.integration.test.ts12.4 kB
import assert from "node:assert/strict" import { after, before, describe, test } from "node:test" import { SqliteDb } from "#db/sqlite-db" import { SqliteSchemaManager } from "#db/sqlite-schema-manager" import { DefaultEmbeddingService } from "#embeddings/default-embedding-service" import { logger } from "#logger" import type { EmbeddingService, Entity, EntityEmbedding, Relation, } from "#types" describe("SQLite Storage Provider Integration Tests", () => { let storage: SqliteDb let schemaManager: SqliteSchemaManager let embeddingService: EmbeddingService before(async () => { // Initialize a deterministic embedding service for testing embeddingService = new DefaultEmbeddingService({ logger }) // Get dimensions from embedding service const dimensions = embeddingService.getModelInfo().dimensions // Initialize database with the embedding service storage = new SqliteDb(":memory:", logger, { vectorDimensions: dimensions, }) // Initialize schema with correct dimensions schemaManager = new SqliteSchemaManager( storage.dbInstance, logger, dimensions ) await schemaManager.initializeSchema() }) after(() => { storage.dbInstance.close() }) describe("sqlite-vec Extension", () => { test("extension loads successfully", () => { const result = storage.dbInstance .sql`SELECT vec_version() as version`.get<{ version: string }>() assert.ok(result?.version, "vec_version() should return a version string") console.log(`sqlite-vec version: ${result?.version}`) }) test("embeddings virtual table exists", () => { const result = storage.dbInstance.sql` SELECT name FROM sqlite_master WHERE type='table' AND name='embeddings' `.get() assert.ok(result, "embeddings virtual table should exist") }) test("vec0 functions are available", () => { const dimensions = embeddingService.getModelInfo().dimensions const testVec = [0.1, 0.2, 0.3] // We need to pad the vector to match the expected dimensions const paddedVec = testVec.concat( new Array(dimensions - testVec.length).fill(0) ) // Convert to Uint8Array format that sqlite-vec expects const float32Vec = new Float32Array(paddedVec) const vecBlob = new Uint8Array(float32Vec.buffer) const result = storage.dbInstance.sql<{ vec1: Uint8Array vec2: Uint8Array }>` SELECT vec_distance_cosine(${"$vec1"}, ${"$vec2"}) as distance `.get<{ distance: number }>({ vec1: vecBlob, vec2: vecBlob }) // Use tolerance for floating-point comparison assert.ok(result, "Should return a result") assert.ok( result.distance < 1e-10, `Identical vectors should have near-zero cosine distance, got ${result.distance}` ) }) }) describe("Vector Operations", () => { const testEntity: Entity = { name: "test-entity-vec", entityType: "feature", observations: ["test observation for vector ops"], } let testEmbedding: EntityEmbedding before(async () => { await storage.createEntities([testEntity]) const firstObservation = testEntity.observations[0] assert.ok( firstObservation, "Test entity should have at least one observation" ) const vector = await embeddingService.generateEmbedding(firstObservation) testEmbedding = { vector, model: embeddingService.getModelInfo().name, lastUpdated: Date.now(), } }) after(async () => { // Clean up test entity to avoid interfering with other tests await storage.deleteEntities([testEntity.name]) }) test("store and retrieve an embedding", async () => { await storage.updateEntityEmbedding(testEntity.name, testEmbedding) const retrieved = await storage.getEntityEmbedding(testEntity.name) assert.ok(retrieved, "Should retrieve an embedding") assert.deepStrictEqual( retrieved.vector, testEmbedding.vector, "Retrieved vector should match the original" ) assert.strictEqual( retrieved.vector.length, embeddingService.getModelInfo().dimensions, "Vector should have correct dimensions" ) }) test("rejects vector with wrong dimensions", async () => { const wrongDimEmbedding: EntityEmbedding = { ...testEmbedding, vector: [0.1, 0.2, 0.3], } // This test needs to be adapted; the vector store might throw the error. // The current implementation of updateEntityEmbedding does not check dimensions. // Let's check the vector store directly. const vectorStore = (storage as any).vectorStore await assert.rejects(async () => { await vectorStore.addVector(testEntity.name, wrongDimEmbedding.vector) }, /Vector dimension mismatch/) }) }) describe("Similarity Search", () => { const entities: Entity[] = [ { name: "cat-sim", entityType: "component", observations: ["a small domesticated carnivorous mammal with soft fur"], }, { name: "dog-sim", entityType: "component", observations: [ "a domesticated carnivorous mammal that typically has a long snout", ], }, { name: "car-sim", entityType: "component", observations: [ "a four-wheeled road vehicle that is powered by an engine", ], }, ] before(async () => { for (const entity of entities) { await storage.createEntities([entity]) const firstObservation = entity.observations[0] assert.ok( firstObservation, "Entity should have at least one observation" ) const vector = await embeddingService.generateEmbedding(firstObservation) await storage.updateEntityEmbedding(entity.name, { vector, model: embeddingService.getModelInfo().name, lastUpdated: Date.now(), }) } }) test("findSimilarEntities returns ranked results", async () => { const queryVector = await embeddingService.generateEmbedding("feline") const results = await storage.findSimilarEntities(queryVector, 3) // Verify we get 3 results assert.strictEqual(results.length, 3, "Should return 3 results") // Verify all expected entities are present (order may vary with deterministic embeddings) const resultNames = results.map((r) => r.name) assert.ok( resultNames.includes("cat-sim"), "Results should include 'cat-sim'" ) assert.ok( resultNames.includes("dog-sim"), "Results should include 'dog-sim'" ) assert.ok( resultNames.includes("car-sim"), "Results should include 'car-sim'" ) // Verify similarity scores are properly ordered (descending) assert.ok(results[0], "First result should exist") assert.ok(results[1], "Second result should exist") assert.ok(results[2], "Third result should exist") assert.ok( results[0].similarity >= results[1].similarity, "Similarity scores should be in descending order" ) assert.ok( results[1].similarity >= results[2].similarity, "Similarity scores should be in descending order" ) // Verify all similarity scores are valid for (const result of results) { assert.ok( result.similarity >= 0 && result.similarity <= 1, `Similarity should be in [0, 1] range, got ${result.similarity}` ) } }) test("similarity scores are between 0 and 1", async () => { const queryVector = await embeddingService.generateEmbedding("animal") const results = await storage.findSimilarEntities(queryVector, 1) assert.ok(results[0], "First result should exist") assert.ok( results[0].similarity >= 0 && results[0].similarity <= 1, "Similarity should be in [0, 1] range" ) }) test("respects the limit parameter", async () => { const queryVector = await embeddingService.generateEmbedding("mammal") const results = await storage.findSimilarEntities(queryVector, 2) assert.strictEqual(results.length, 2, "Should return exactly 2 results") }) }) describe("Semantic Search", () => { const entitiesForSearch: Entity[] = [ { name: "auth-feature-sem", entityType: "feature", observations: ["Implements OAuth2 and JWT for user authentication."], }, { name: "ui-component-sem", entityType: "component", observations: ["A button component for the main UI."], }, ] const relation: Relation = { from: "auth-feature-sem", to: "ui-component-sem", relationType: "relates_to", } before(async () => { await storage.createEntities(entitiesForSearch) await storage.createRelations([relation]) for (const entity of entitiesForSearch) { const firstObservation = entity.observations[0] assert.ok( firstObservation, "Entity should have at least one observation" ) const vector = await embeddingService.generateEmbedding(firstObservation) await storage.updateEntityEmbedding(entity.name, { vector, model: embeddingService.getModelInfo().name, lastUpdated: Date.now(), }) } }) test("performs semantic search and includes relations", async () => { const queryVector = await embeddingService.generateEmbedding( "user login security" ) const graph = await storage.semanticSearch("user login security", { queryVector, limit: 2, }) assert.ok(graph.entities.length > 0, "Should find at least one entity") const entityNames = graph.entities.map((e) => e.name) assert.ok( entityNames.includes("auth-feature-sem"), "Should find the 'auth-feature-sem' entity" ) // This part of the test might be flaky depending on the search results. // If both are returned, check for the relation. if ( entityNames.includes("auth-feature-sem") && entityNames.includes("ui-component-sem") ) { assert.ok( graph.relations.length >= 1, "Should include relations between found entities" ) assert.ok(graph.relations[0], "First relation should exist") assert.strictEqual(graph.relations[0].from, "auth-feature-sem") } }) test("falls back to text search if no queryVector is provided", async () => { // This will log a warning, which is expected. const graph = await storage.semanticSearch("OAuth2") assert.ok( graph.entities.length > 0, "Should find entities via text search fallback" ) assert.ok(graph.entities[0], "First entity should exist") assert.strictEqual(graph.entities[0].name, "auth-feature-sem") }) }) describe("Diagnostics", () => { before(async () => { const entity: Entity = { name: "diag-entity-unique", entityType: "test", observations: ["diag"], } await storage.createEntities([entity]) const vector = await embeddingService.generateEmbedding("diag") await storage.updateEntityEmbedding(entity.name, { vector, model: embeddingService.getModelInfo().name, lastUpdated: Date.now(), }) }) test("diagnoseVectorSearch returns correct information", async () => { const diagnostics = await storage.diagnoseVectorSearch() assert.strictEqual( diagnostics.vectorSearchAvailable, true, "Vector search should be available" ) assert.ok( typeof diagnostics.entitiesWithEmbeddings === "number" && diagnostics.entitiesWithEmbeddings >= 1, "Should have at least 1 entity with an embedding" ) assert.ok( typeof diagnostics.totalEntities === "number" && diagnostics.totalEntities >= 1, "Should have at least 1 total entity" ) assert.ok( (diagnostics.sampleEmbeddings as any[]).length >= 1, "Should have at least 1 sample embedding" ) }) }) })

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/Takin-Profit/devflow-mcp'

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