UNPKG

@mastra/core

Version:

Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.

305 lines (208 loc) • 7.87 kB
# libSQL vector store The libSQL storage implementation provides a SQLite-compatible vector search [libSQL](https://github.com/tursodatabase/libsql), a fork of SQLite with vector extensions, and [Turso](https://turso.tech/) with vector extensions, offering a lightweight and efficient vector database solution. It's part of the `@mastra/libsql` package and offers efficient vector similarity search with metadata filtering. ## Installation **npm**: ```bash npm install @mastra/libsql@latest ``` **pnpm**: ```bash pnpm add @mastra/libsql@latest ``` **Yarn**: ```bash yarn add @mastra/libsql@latest ``` **Bun**: ```bash bun add @mastra/libsql@latest ``` ## Usage ```typescript import { LibSQLVector } from "@mastra/libsql"; // Create a new vector store instance const store = new LibSQLVector({ id: 'libsql-vector', url: process.env.DATABASE_URL, // Optional: for Turso cloud databases authToken: process.env.DATABASE_AUTH_TOKEN, }); // Create an index await store.createIndex({ indexName: "myCollection", dimension: 1536, }); // Add vectors with metadata const vectors = [[0.1, 0.2, ...], [0.3, 0.4, ...]]; const metadata = [ { text: "first document", category: "A" }, { text: "second document", category: "B" } ]; await store.upsert({ indexName: "myCollection", vectors, metadata, }); // Query similar vectors const queryVector = [0.1, 0.2, ...]; const results = await store.query({ indexName: "myCollection", queryVector, topK: 10, // top K results filter: { category: "A" } // optional metadata filter }); ``` ## Constructor options **url** (`string`): libSQL database URL. Use ':memory:' for in-memory database, 'file:dbname.db' for local file, or a libSQL-compatible connection string like 'libsql://your-database.turso.io'. **authToken** (`string`): Authentication token for Turso cloud databases **syncUrl** (`string`): URL for database replication (Turso specific) **syncInterval** (`number`): Interval in milliseconds for database sync (Turso specific) ## Methods ### `createIndex()` Creates a new vector collection. The index name must start with a letter or underscore and can only contain letters, numbers, and underscores. The dimension must be a positive integer. **indexName** (`string`): Name of the index to create **dimension** (`number`): Vector dimension size (must match your embedding model) **metric** (`'cosine' | 'euclidean' | 'dotproduct'`): Distance metric for similarity search. Note: Currently only cosine similarity is supported by libSQL. (Default: `cosine`) ### `upsert()` Adds or updates vectors and their metadata in the index. Uses a transaction to ensure all vectors are inserted atomically - if any insert fails, the entire operation is rolled back. **indexName** (`string`): Name of the index to insert into **vectors** (`number[][]`): Array of embedding vectors **metadata** (`Record<string, any>[]`): Metadata for each vector **ids** (`string[]`): Optional vector IDs (auto-generated if not provided) ### `query()` Searches for similar vectors with optional metadata filtering. **indexName** (`string`): Name of the index to search in **queryVector** (`number[]`): Query vector to find similar vectors for **topK** (`number`): Number of results to return (Default: `10`) **filter** (`Filter`): Metadata filters **includeVector** (`boolean`): Whether to include vector data in results (Default: `false`) **minScore** (`number`): Minimum similarity score threshold (Default: `0`) ### `describeIndex()` Gets information about an index. **indexName** (`string`): Name of the index to describe Returns: ```typescript interface IndexStats { dimension: number count: number metric: 'cosine' | 'euclidean' | 'dotproduct' } ``` ### `deleteIndex()` Deletes an index and all its data. **indexName** (`string`): Name of the index to delete ### `listIndexes()` Lists all vector indexes in the database. Returns: `Promise<string[]>` ### `truncateIndex()` Removes all vectors from an index while keeping the index structure. **indexName** (`string`): Name of the index to truncate ### `updateVector()` Update a single vector by ID or by metadata filter. Either `id` or `filter` must be provided, but not both. **indexName** (`string`): Name of the index containing the vector **id** (`string`): ID of the vector entry to update (mutually exclusive with filter) **filter** (`Record<string, any>`): Metadata filter to identify vector(s) to update (mutually exclusive with id) **update** (`object`): Update data containing vector and/or metadata **update.vector** (`number[]`): New vector data to update **update.metadata** (`Record<string, any>`): New metadata to update ### `deleteVector()` Deletes a specific vector entry from an index by its ID. **indexName** (`string`): Name of the index containing the vector **id** (`string`): ID of the vector entry to delete ### `deleteVectors()` Delete multiple vectors by IDs or by metadata filter. Either `ids` or `filter` must be provided, but not both. **indexName** (`string`): Name of the index containing the vectors to delete **ids** (`string[]`): Array of vector IDs to delete (mutually exclusive with filter) **filter** (`Record<string, any>`): Metadata filter to identify vectors to delete (mutually exclusive with ids) ## Response types Query results are returned in this format: ```typescript interface QueryResult { id: string score: number metadata: Record<string, any> vector?: number[] // Only included if includeVector is true } ``` ## Error handling The store throws specific errors for different failure cases: ```typescript try { await store.query({ indexName: 'my-collection', queryVector: queryVector, }) } catch (error) { // Handle specific error cases if (error.message.includes('Invalid index name format')) { console.error( 'Index name must start with a letter/underscore and contain only alphanumeric characters', ) } else if (error.message.includes('Table not found')) { console.error('The specified index does not exist') } else { console.error('Vector store error:', error.message) } } ``` Common error cases include: - Invalid index name format - Invalid vector dimensions - Table/index not found - Database connection issues - Transaction failures during upsert ## Usage example ### Local embeddings with fastembed Embeddings are numeric vectors used by memory's `semanticRecall` to retrieve related messages by meaning (not keywords). This setup uses `@mastra/fastembed` to generate vector embeddings. Install `fastembed` to get started: **npm**: ```bash npm install @mastra/fastembed@latest ``` **pnpm**: ```bash pnpm add @mastra/fastembed@latest ``` **Yarn**: ```bash yarn add @mastra/fastembed@latest ``` **Bun**: ```bash bun add @mastra/fastembed@latest ``` Add the following to your agent: ```typescript import { Memory } from '@mastra/memory' import { Agent } from '@mastra/core/agent' import { LibSQLStore, LibSQLVector } from '@mastra/libsql' import { fastembed } from '@mastra/fastembed' export const libsqlAgent = new Agent({ id: 'libsql-agent', name: 'libSQL Agent', instructions: 'You are an AI agent with the ability to automatically recall memories from previous interactions.', model: 'openai/gpt-5.4', memory: new Memory({ storage: new LibSQLStore({ id: 'libsql-agent-storage', url: 'file:libsql-agent.db', }), vector: new LibSQLVector({ id: 'libsql-agent-vector', url: 'file:libsql-agent.db', }), embedder: fastembed, options: { lastMessages: 10, semanticRecall: { topK: 3, messageRange: 2, }, generateTitle: true, // Explicitly enable automatic title generation }, }), }) ``` ## Related - [Metadata Filters](https://mastra.ai/reference/rag/metadata-filters)