VibecoderMcSwaggins commited on
Commit
055a3a7
·
1 Parent(s): 3aa91e9

fix(rag): apply lazy imports and use centralized config

Browse files

- Remove unused TYPE_CHECKING block (imports are in __init__)
- Use settings.openai_model instead of hard-coded "gpt-4o-mini"
- Fix line length in clear_collection() method
- Change Document type hint to Any for lazy import compatibility

Files changed (1) hide show
  1. src/services/llamaindex_rag.py +43 -22
src/services/llamaindex_rag.py CHANGED
@@ -1,14 +1,11 @@
1
- """LlamaIndex RAG service for evidence retrieval and indexing."""
 
 
 
2
 
3
  from typing import Any
4
 
5
- import chromadb
6
  import structlog
7
- from llama_index.core import Document, Settings, StorageContext, VectorStoreIndex
8
- from llama_index.core.retrievers import VectorIndexRetriever
9
- from llama_index.embeddings.openai import OpenAIEmbedding
10
- from llama_index.llms.openai import OpenAI
11
- from llama_index.vector_stores.chroma import ChromaVectorStore
12
 
13
  from src.utils.config import settings
14
  from src.utils.models import Evidence
@@ -35,22 +32,44 @@ class LlamaIndexRAGService:
35
  embedding_model: OpenAI embedding model to use
36
  similarity_top_k: Number of top results to retrieve
37
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  self.collection_name = collection_name
39
  self.persist_dir = persist_dir or settings.chroma_db_path
40
  self.similarity_top_k = similarity_top_k
41
 
42
- # Configure LlamaIndex settings
43
- Settings.llm = OpenAI(
44
- model="gpt-4o-mini",
45
  api_key=settings.openai_api_key,
46
  )
47
- Settings.embed_model = OpenAIEmbedding(
48
  model=embedding_model,
49
  api_key=settings.openai_api_key,
50
  )
51
 
52
  # Initialize ChromaDB client
53
- self.chroma_client = chromadb.PersistentClient(path=self.persist_dir)
54
 
55
  # Get or create collection
56
  try:
@@ -61,18 +80,18 @@ class LlamaIndexRAGService:
61
  logger.info("created_new_collection", name=self.collection_name)
62
 
63
  # Initialize vector store and index
64
- self.vector_store = ChromaVectorStore(chroma_collection=self.collection)
65
- self.storage_context = StorageContext.from_defaults(vector_store=self.vector_store)
66
 
67
  # Try to load existing index, or create empty one
68
  try:
69
- self.index = VectorStoreIndex.from_vector_store(
70
  vector_store=self.vector_store,
71
  storage_context=self.storage_context,
72
  )
73
  logger.info("loaded_existing_index")
74
  except Exception:
75
- self.index = VectorStoreIndex([], storage_context=self.storage_context)
76
  logger.info("created_new_index")
77
 
78
  def ingest_evidence(self, evidence_list: list[Evidence]) -> None:
@@ -97,7 +116,7 @@ class LlamaIndexRAGService:
97
  "authors": ", ".join(evidence.citation.authors),
98
  }
99
 
100
- doc = Document(
101
  text=evidence.content,
102
  metadata=metadata,
103
  doc_id=evidence.citation.url, # Use URL as unique ID
@@ -113,7 +132,7 @@ class LlamaIndexRAGService:
113
  logger.error("failed_to_ingest_evidence", error=str(e))
114
  raise
115
 
116
- def ingest_documents(self, documents: list[Document]) -> None:
117
  """
118
  Ingest raw LlamaIndex Documents.
119
 
@@ -146,7 +165,7 @@ class LlamaIndexRAGService:
146
  k = top_k or self.similarity_top_k
147
 
148
  # Create retriever
149
- retriever = VectorIndexRetriever(
150
  index=self.index,
151
  similarity_top_k=k,
152
  )
@@ -205,9 +224,11 @@ class LlamaIndexRAGService:
205
  try:
206
  self.chroma_client.delete_collection(self.collection_name)
207
  self.collection = self.chroma_client.create_collection(self.collection_name)
208
- self.vector_store = ChromaVectorStore(chroma_collection=self.collection)
209
- self.storage_context = StorageContext.from_defaults(vector_store=self.vector_store)
210
- self.index = VectorStoreIndex([], storage_context=self.storage_context)
 
 
211
  logger.info("cleared_collection", name=self.collection_name)
212
  except Exception as e:
213
  logger.error("failed_to_clear_collection", error=str(e))
 
1
+ """LlamaIndex RAG service for evidence retrieval and indexing.
2
+
3
+ Requires optional dependencies: uv sync --extra modal
4
+ """
5
 
6
  from typing import Any
7
 
 
8
  import structlog
 
 
 
 
 
9
 
10
  from src.utils.config import settings
11
  from src.utils.models import Evidence
 
32
  embedding_model: OpenAI embedding model to use
33
  similarity_top_k: Number of top results to retrieve
34
  """
35
+ # Lazy import - only when instantiated
36
+ try:
37
+ import chromadb
38
+ from llama_index.core import Document, Settings, StorageContext, VectorStoreIndex
39
+ from llama_index.core.retrievers import VectorIndexRetriever
40
+ from llama_index.embeddings.openai import OpenAIEmbedding
41
+ from llama_index.llms.openai import OpenAI
42
+ from llama_index.vector_stores.chroma import ChromaVectorStore
43
+ except ImportError as e:
44
+ raise ImportError(
45
+ "LlamaIndex dependencies not installed. Run: uv sync --extra modal"
46
+ ) from e
47
+
48
+ # Store references for use in other methods
49
+ self._chromadb = chromadb
50
+ self._Document = Document
51
+ self._Settings = Settings
52
+ self._StorageContext = StorageContext
53
+ self._VectorStoreIndex = VectorStoreIndex
54
+ self._VectorIndexRetriever = VectorIndexRetriever
55
+ self._ChromaVectorStore = ChromaVectorStore
56
+
57
  self.collection_name = collection_name
58
  self.persist_dir = persist_dir or settings.chroma_db_path
59
  self.similarity_top_k = similarity_top_k
60
 
61
+ # Configure LlamaIndex settings (use centralized config)
62
+ self._Settings.llm = OpenAI(
63
+ model=settings.openai_model,
64
  api_key=settings.openai_api_key,
65
  )
66
+ self._Settings.embed_model = OpenAIEmbedding(
67
  model=embedding_model,
68
  api_key=settings.openai_api_key,
69
  )
70
 
71
  # Initialize ChromaDB client
72
+ self.chroma_client = self._chromadb.PersistentClient(path=self.persist_dir)
73
 
74
  # Get or create collection
75
  try:
 
80
  logger.info("created_new_collection", name=self.collection_name)
81
 
82
  # Initialize vector store and index
83
+ self.vector_store = self._ChromaVectorStore(chroma_collection=self.collection)
84
+ self.storage_context = self._StorageContext.from_defaults(vector_store=self.vector_store)
85
 
86
  # Try to load existing index, or create empty one
87
  try:
88
+ self.index = self._VectorStoreIndex.from_vector_store(
89
  vector_store=self.vector_store,
90
  storage_context=self.storage_context,
91
  )
92
  logger.info("loaded_existing_index")
93
  except Exception:
94
+ self.index = self._VectorStoreIndex([], storage_context=self.storage_context)
95
  logger.info("created_new_index")
96
 
97
  def ingest_evidence(self, evidence_list: list[Evidence]) -> None:
 
116
  "authors": ", ".join(evidence.citation.authors),
117
  }
118
 
119
+ doc = self._Document(
120
  text=evidence.content,
121
  metadata=metadata,
122
  doc_id=evidence.citation.url, # Use URL as unique ID
 
132
  logger.error("failed_to_ingest_evidence", error=str(e))
133
  raise
134
 
135
+ def ingest_documents(self, documents: list[Any]) -> None:
136
  """
137
  Ingest raw LlamaIndex Documents.
138
 
 
165
  k = top_k or self.similarity_top_k
166
 
167
  # Create retriever
168
+ retriever = self._VectorIndexRetriever(
169
  index=self.index,
170
  similarity_top_k=k,
171
  )
 
224
  try:
225
  self.chroma_client.delete_collection(self.collection_name)
226
  self.collection = self.chroma_client.create_collection(self.collection_name)
227
+ self.vector_store = self._ChromaVectorStore(chroma_collection=self.collection)
228
+ self.storage_context = self._StorageContext.from_defaults(
229
+ vector_store=self.vector_store
230
+ )
231
+ self.index = self._VectorStoreIndex([], storage_context=self.storage_context)
232
  logger.info("cleared_collection", name=self.collection_name)
233
  except Exception as e:
234
  logger.error("failed_to_clear_collection", error=str(e))