Skip to content

Commit 074d1e1

Browse files
authored
feat(community): allow metadata generics to flow through LibSQLVectorStore (#7208)
1 parent 54decfe commit 074d1e1

1 file changed

Lines changed: 23 additions & 16 deletions

File tree

  • libs/langchain-community/src/vectorstores

libs/langchain-community/src/vectorstores/libsql.ts

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import type { EmbeddingsInterface } from "@langchain/core/embeddings";
33
import { VectorStore } from "@langchain/core/vectorstores";
44
import type { Client, InStatement } from "@libsql/client";
55

6+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7+
type MetadataDefault = Record<string, any>;
8+
69
/**
710
* Interface for LibSQLVectorStore configuration options.
811
*/
@@ -18,8 +21,10 @@ export interface LibSQLVectorStoreArgs {
1821
/**
1922
* A vector store using LibSQL/Turso for storage and retrieval.
2023
*/
21-
export class LibSQLVectorStore extends VectorStore {
22-
declare FilterType: (doc: Document) => boolean;
24+
export class LibSQLVectorStore<
25+
Metadata extends MetadataDefault = MetadataDefault
26+
> extends VectorStore {
27+
declare FilterType: (doc: Document<Metadata>) => boolean;
2328

2429
private db;
2530

@@ -51,10 +56,10 @@ export class LibSQLVectorStore extends VectorStore {
5156

5257
/**
5358
* Adds documents to the vector store.
54-
* @param {Document[]} documents - The documents to add.
59+
* @param {Document<Metadata>[]} documents - The documents to add.
5560
* @returns {Promise<string[]>} The IDs of the added documents.
5661
*/
57-
async addDocuments(documents: Document[]): Promise<string[]> {
62+
async addDocuments(documents: Document<Metadata>[]): Promise<string[]> {
5863
const texts = documents.map(({ pageContent }) => pageContent);
5964
const embeddings = await this.embeddings.embedDocuments(texts);
6065

@@ -64,12 +69,12 @@ export class LibSQLVectorStore extends VectorStore {
6469
/**
6570
* Adds vectors to the vector store.
6671
* @param {number[][]} vectors - The vectors to add.
67-
* @param {Document[]} documents - The documents associated with the vectors.
72+
* @param {Document<Metadata>[]} documents - The documents associated with the vectors.
6873
* @returns {Promise<string[]>} The IDs of the added vectors.
6974
*/
7075
async addVectors(
7176
vectors: number[][],
72-
documents: Document[]
77+
documents: Document<Metadata>[]
7378
): Promise<string[]> {
7479
const rows = vectors.map((embedding, idx) => ({
7580
content: documents[idx].pageContent,
@@ -102,14 +107,14 @@ export class LibSQLVectorStore extends VectorStore {
102107
* Performs a similarity search using a vector query and returns documents with their scores.
103108
* @param {number[]} query - The query vector.
104109
* @param {number} k - The number of results to return.
105-
* @returns {Promise<[Document, number][]>} An array of tuples containing the similar documents and their scores.
110+
* @returns {Promise<[Document<Metadata>, number][]>} An array of tuples containing the similar documents and their scores.
106111
*/
107112
async similaritySearchVectorWithScore(
108113
query: number[],
109114
k: number
110115
// filter is currently unused
111116
// filter?: this["FilterType"]
112-
): Promise<[Document, number][]> {
117+
): Promise<[Document<Metadata>, number][]> {
113118
// Potential SQL injection risk if query vector is not properly sanitized.
114119
if (!query.every((num) => typeof num === "number" && !Number.isNaN(num))) {
115120
throw new Error("Invalid query vector: all elements must be numbers");
@@ -130,7 +135,7 @@ export class LibSQLVectorStore extends VectorStore {
130135
return results.rows.map((row: any) => {
131136
const metadata = JSON.parse(row.metadata);
132137

133-
const doc = new Document({
138+
const doc = new Document<Metadata>({
134139
id: String(row.id),
135140
metadata,
136141
pageContent: row.content,
@@ -175,12 +180,12 @@ export class LibSQLVectorStore extends VectorStore {
175180
* @param {LibSQLVectorStoreArgs} [options] - Configuration options for the vector store.
176181
* @returns {Promise<LibSQLVectorStore>} A new LibSQLVectorStore instance.
177182
*/
178-
static async fromTexts(
183+
static async fromTexts<Metadata extends MetadataDefault = MetadataDefault>(
179184
texts: string[],
180-
metadatas: object[] | object,
185+
metadatas: Metadata[] | Metadata,
181186
embeddings: EmbeddingsInterface,
182187
options: LibSQLVectorStoreArgs
183-
): Promise<LibSQLVectorStore> {
188+
): Promise<LibSQLVectorStore<Metadata>> {
184189
const docs = texts.map((text, i) => {
185190
const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas;
186191

@@ -198,12 +203,14 @@ export class LibSQLVectorStore extends VectorStore {
198203
* @param {LibSQLVectorStoreArgs} [options] - Configuration options for the vector store.
199204
* @returns {Promise<LibSQLVectorStore>} A new LibSQLVectorStore instance.
200205
*/
201-
static async fromDocuments(
202-
docs: Document[],
206+
static async fromDocuments<
207+
Metadata extends MetadataDefault = MetadataDefault
208+
>(
209+
docs: Document<Metadata>[],
203210
embeddings: EmbeddingsInterface,
204211
options: LibSQLVectorStoreArgs
205-
): Promise<LibSQLVectorStore> {
206-
const instance = new this(embeddings, options);
212+
): Promise<LibSQLVectorStore<Metadata>> {
213+
const instance = new this<Metadata>(embeddings, options);
207214

208215
await instance.addDocuments(docs);
209216

0 commit comments

Comments
 (0)