import { VectorStore, VectorStoreRetriever, VectorStoreRetrieverInput, } from "../vectorstores/base.js"; import { Document } from "../document.js"; export type ScoreThresholdRetrieverInput = Omit< VectorStoreRetrieverInput, "k" > & { maxK?: number; kIncrement?: number; minSimilarityScore: number; }; export class ScoreThresholdRetriever< V extends VectorStore > extends VectorStoreRetriever { minSimilarityScore: number; kIncrement = 10; maxK = 100; constructor(input: ScoreThresholdRetrieverInput) { super(input); this.maxK = input.maxK ?? this.maxK; this.minSimilarityScore = input.minSimilarityScore ?? this.minSimilarityScore; this.kIncrement = input.kIncrement ?? this.kIncrement; } async getRelevantDocuments(query: string): Promise { let currentK = 0; let filteredResults: [Document, number][] = []; do { currentK += this.kIncrement; const results = await this.vectorStore.similaritySearchWithScore( query, currentK, this.filter ); filteredResults = results.filter( ([, score]) => score >= this.minSimilarityScore ); } while (filteredResults.length >= currentK && currentK < this.maxK); return filteredResults.map((documents) => documents[0]).slice(0, this.maxK); } static fromVectorStore( vectorStore: V, options: Omit, "vectorStore"> ) { return new this({ ...options, vectorStore }); } }