CoolFace
Apppublic

yashasvi0409/Document_Intelligence

sourceHugging Faceupdated 7mo agoView on Hugging Face
0likes
vector_store.py119 linesDownload Raw Back to root
1import faiss2import numpy as np3 4# ✅ Import your embedding function (same file you already use in main.py)5from embeddings import embed_texts6 7 8class VectorStore:9    def __init__(self, dimension: int):10        # Inner Product index (works well if you normalize embeddings)11        self.index = faiss.IndexFlatIP(dimension)12        self.text_chunks = []13        self.metadata = []14 15    def add(self, embeddings, chunks, sources):16        """17        embeddings: list/np.array of shape (N, dim)18        chunks: list[str] length N19        sources: list[Any] length N20        """21        emb = np.array(embeddings, dtype="float32")22 23        # FAISS expects 2D array24        if emb.ndim == 1:25            emb = emb.reshape(1, -1)26 27        self.index.add(emb)28        self.text_chunks.extend(chunks)29        self.metadata.extend(sources)30 31    def search(self, query_embedding, top_k: int = 3):32        """33        query_embedding: np.array shape (1, dim) or (dim,)34        returns list of dicts with text/source/score35        """36        q = np.array(query_embedding, dtype="float32")37 38        # FAISS expects 2D array: (1, dim)39        if q.ndim == 1:40            q = q.reshape(1, -1)41 42        scores, indices = self.index.search(q, top_k)43 44        results = []45        for idx, score in zip(indices[0], scores[0]):46            if idx == -1:47                continue48            if idx >= len(self.text_chunks):49                continue50 51            results.append({52                "text": self.text_chunks[idx],53                "source": self.metadata[idx],54                "score": float(score)55            })56 57        return results58 59    # ✅ NEW: This is what routes.py should call60    def query(self, question: str, top_k: int = 3):61        """62        Converts question -> embedding, searches FAISS,63        then returns output in your UI format.64        """65        question = (question or "").strip()66        if not question:67            return {68                "answer": "Please ask a question.",69                "confidence": "LOW",70                "similarity_score": 0.0,71                "source_documents": []72            }73 74        # ✅ Get embedding for the question (embed_texts expects list[str])75        q_embs = embed_texts([question])76 77        # embed_texts may return numpy array or list78        q_embs = np.array(q_embs, dtype="float32")79 80        # Ensure shape (1, dim)81        if q_embs.ndim == 1:82            q_embs = q_embs.reshape(1, -1)83 84        # ✅ Search85        hits = self.search(q_embs[0], top_k=top_k)86 87        if not hits:88            return {89                "answer": "No relevant information found in the uploaded documents.",90                "confidence": "LOW",91                "similarity_score": 0.0,92                "source_documents": []93            }94 95        # ✅ Build answer from best chunk (top hit)96        best = hits[0]97        answer_text = best.get("text", "—")98        best_score = float(best.get("score", 0.0))99 100        # ✅ Simple confidence mapping101        if best_score >= 0.75:102            conf = "HIGH"103        elif best_score >= 0.45:104            conf = "MEDIUM"105        else:106            conf = "LOW"107 108        sources = []109        for h in hits:110            src = h.get("source")111            if src and src not in sources:112                sources.append(src)113 114        return {115            "answer": answer_text,116            "confidence": conf,117            "similarity_score": best_score,118            "source_documents": sources119        }