/**
* Vector Tools Tests
*
* Tests for SQLite vector similarity search tools.
*/
import { describe, it, expect, beforeEach, afterEach } from "vitest";
import {
createTestAdapter,
type TestAdapter,
} from "../../utils/test-adapter.js";
describe("Vector Tools", () => {
let adapter: TestAdapter;
let tools: Map<string, (params: unknown) => Promise<unknown>>;
beforeEach(async () => {
adapter = createTestAdapter();
await adapter.connect({
type: "sqlite",
connectionString: ":memory:",
});
tools = new Map();
const toolDefs = adapter.getToolDefinitions();
const context = { scopes: ["read", "write", "admin"] };
for (const tool of toolDefs) {
tools.set(tool.name, (params) => tool.handler(params, context as never));
}
});
afterEach(async () => {
await adapter.disconnect();
});
describe("sqlite_vector_create_table", () => {
it("should create vector table", async () => {
const result = await tools.get("sqlite_vector_create_table")?.({
tableName: "embeddings",
dimensions: 3,
});
expect(result).toHaveProperty("success", true);
const tables = await adapter.listTables();
expect(tables.map((t) => t.name)).toContain("embeddings");
});
});
describe("sqlite_vector_store", () => {
it("should store a vector", async () => {
await adapter.executeWriteQuery(`
CREATE TABLE vectors (id INTEGER PRIMARY KEY, embedding TEXT)
`);
const result = await tools.get("sqlite_vector_store")?.({
table: "vectors",
idColumn: "id",
vectorColumn: "embedding",
id: 1,
vector: [0.1, 0.2, 0.3],
});
expect(result).toHaveProperty("success", true);
});
});
describe("sqlite_vector_search", () => {
it("should find similar vectors", async () => {
await adapter.executeWriteQuery(`
CREATE TABLE vectors (id INTEGER PRIMARY KEY, embedding TEXT, label TEXT)
`);
// Store some vectors
await adapter.executeWriteQuery(`
INSERT INTO vectors (embedding, label) VALUES
('[1.0, 0.0, 0.0]', 'x-axis'),
('[0.0, 1.0, 0.0]', 'y-axis'),
('[0.707, 0.707, 0.0]', 'xy-diagonal')
`);
// Search for vector similar to x-axis
const result = (await tools.get("sqlite_vector_search")?.({
table: "vectors",
vectorColumn: "embedding",
queryVector: [0.9, 0.1, 0.0],
metric: "cosine",
limit: 2,
})) as { results: { label: string; _similarity: number }[] };
// x-axis should be most similar
expect(result.results[0]?.label).toBe("x-axis");
});
});
describe("sqlite_vector_distance", () => {
it("should calculate cosine similarity", async () => {
const result = (await tools.get("sqlite_vector_distance")?.({
vector1: [1, 0, 0],
vector2: [1, 0, 0],
metric: "cosine",
})) as { value: number };
expect(result.value).toBe(1); // Same vector = similarity 1
});
it("should calculate euclidean distance", async () => {
const result = (await tools.get("sqlite_vector_distance")?.({
vector1: [0, 0],
vector2: [3, 4],
metric: "euclidean",
})) as { value: number };
expect(result.value).toBe(5); // 3-4-5 triangle
});
});
describe("sqlite_vector_normalize", () => {
it("should normalize a vector", async () => {
const result = (await tools.get("sqlite_vector_normalize")?.({
vector: [3, 4],
})) as { normalized: number[] };
expect(result.normalized[0]).toBeCloseTo(0.6, 5);
expect(result.normalized[1]).toBeCloseTo(0.8, 5);
});
});
});