report-analyzer / vector_store.py
mfallahian's picture
Upload 11 files
e2df10e verified
Raw
History Blame Contribute Delete
2.6 kB
"""Vector store operations for document retrieval."""
from __future__ import annotations
from typing import List, Sequence, Tuple
from langchain_chroma import Chroma
from langchain_core.documents import Document
from langchain_openai import OpenAIEmbeddings
from config import COLLECTION_NAME, EMBEDDING_MODEL, VECTOR_DIR
from helpers import _chunk_section_or_preview, _clip
def load_vector_store() -> Tuple[Chroma | None, str | None]:
"""Load the Chroma vector store."""
if not VECTOR_DIR.exists():
return None, "Vector store not found. Run `python build_vectordb.py --recreate` first."
try:
embeddings = OpenAIEmbeddings(model=EMBEDDING_MODEL)
store = Chroma(
collection_name=COLLECTION_NAME,
persist_directory=str(VECTOR_DIR),
embedding_function=embeddings,
)
return store, None
except Exception as exc: # pragma: no cover
return None, f"Failed to load vector store: {exc}"
def retrieve_report_chunks(store: Chroma, query: str, state_slugs: Sequence[str], k: int = 8) -> List[Document]:
"""Retrieve relevant report chunks from vector store."""
target_states = set(state_slugs)
candidates = store.similarity_search(query, k=max(24, k * 4))
filtered = [doc for doc in candidates if doc.metadata.get("state") in target_states]
if not filtered and len(target_states) == 1:
only_state = next(iter(target_states))
try:
filtered = store.similarity_search(query, k=k, filter={"state": only_state})
except Exception:
filtered = []
deduped: List[Document] = []
seen = set()
for doc in filtered:
key = (doc.metadata.get("source"), doc.metadata.get("chunk_id"), doc.page_content[:100])
if key in seen:
continue
seen.add(key)
deduped.append(doc)
if len(deduped) >= k:
break
return deduped
def format_report_context(docs: Sequence[Document]) -> Tuple[str, List[str]]:
"""Format retrieved documents into context string and source references."""
snippets: List[str] = []
source_refs: List[str] = []
for idx, doc in enumerate(docs, start=1):
state_label = doc.metadata.get("state_label") or doc.metadata.get("state", "Unknown")
section_or_preview = _chunk_section_or_preview(doc.page_content)
snippets.append(f"[S{idx}] ({state_label} | {section_or_preview})\n{_clip(doc.page_content)}")
source_refs.append(f"- [S{idx}] {state_label} | {section_or_preview}")
return "\n\n".join(snippets), source_refs