using BLAIzor.Models; using System; using System.Collections.Generic; using System.Linq; namespace BLAIzor.Services { public class LocalVectorSearchService { //private List _cachedContents = new(); //private List _cachedSnippets = new(); private int _cachedContentVersion = -1; private int _cachedSnippetVersion = -1; // Inject any needed services (e.g. DbContext, versioning service) public LocalVectorSearchService() { } //public void SetContentCache(List contents, int contentVersion) //{ // _cachedContents = contents; // _cachedContentVersion = contentVersion; //} //public void SetSnippetCache(List snippets, int snippetVersion) //{ // _cachedSnippets = snippets; // _cachedSnippetVersion = snippetVersion; //} public bool IsContentVersionOutdated(int currentVersion) => currentVersion != _cachedContentVersion; public bool IsSnippetVersionOutdated(int currentVersion) => currentVersion != _cachedSnippetVersion; public List SearchContent(float[] queryVector, List cachedContents, int maxResults = 5) { return cachedContents .Select(c => new { Content = c, Similarity = CosineSimilarity(queryVector, c.Vectors) }) .OrderByDescending(x => x.Similarity) .Take(maxResults) .Select(x => x.Content) .ToList(); } public List SearchSnippets(float[] queryVector, List cachedSnippets, int maxResults = 5) { return cachedSnippets .Select(s => new { Snippet = s, Similarity = CosineSimilarity(queryVector, s.Vectors) }) .OrderByDescending(x => x.Similarity) .Take(maxResults) .Select(x => x.Snippet) .ToList(); } private float CosineSimilarity(float[] vectorA, float[] vectorB) { if (vectorA == null || vectorB == null || vectorA.Length != vectorB.Length) return 0f; float dot = 0f, magA = 0f, magB = 0f; for (int i = 0; i < vectorA.Length; i++) { dot += vectorA[i] * vectorB[i]; magA += vectorA[i] * vectorA[i]; magB += vectorB[i] * vectorB[i]; } if (magA == 0 || magB == 0) return 0f; return dot / ((float)Math.Sqrt(magA) * (float)Math.Sqrt(magB)); } } }