NimrodDev commited on
Commit
dd7779a
·
1 Parent(s): efe7e34
Files changed (1) hide show
  1. rag.py +42 -19
rag.py CHANGED
@@ -1,6 +1,6 @@
1
  # rag.py – bullet-proof and container-safe
2
  from __future__ import annotations
3
- import os, re, json, requests
4
  from functools import lru_cache
5
  from typing import List, Tuple
6
 
@@ -18,11 +18,12 @@ CONFIG = "default"
18
  SPLIT = "train"
19
  LIMIT = 500
20
  LLM_MODEL = "microsoft/DialoGPT-medium"
 
21
  SUPABASE_URL = os.getenv("SUPABASE_URL")
22
  SUPABASE_KEY = os.getenv("SUPABASE_KEY")
23
  HF_TOKEN = os.getenv("HF_TOKEN")
24
 
25
- # Safe cache path for HuggingFace
26
  CACHE_DIR = os.getenv("HF_HOME", "/tmp/hf_cache")
27
  os.makedirs(CACHE_DIR, exist_ok=True)
28
  os.environ["TRANSFORMERS_CACHE"] = CACHE_DIR
@@ -31,7 +32,7 @@ os.environ["HF_HUB_CACHE"] = CACHE_DIR
31
 
32
  supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
33
 
34
- # ------------------------------------------------------------------ INTENT
35
  GREETING_RE = re.compile(r"\b(hi|hello|hey|good morning|good afternoon|good evening)\b", re.I)
36
  THANKS_RE = re.compile(r"\b(thank|thanks|appreciate)\b", re.I)
37
  BYE_RE = re.compile(r"\b(bye|goodbye|see you|later)\b", re.I)
@@ -104,27 +105,33 @@ def get_vectorstore() -> FAISS:
104
  embeddings = None
105
 
106
  try:
 
107
  from langchain_huggingface import HuggingFaceInferenceAPIEmbeddings
108
  embeddings = HuggingFaceInferenceAPIEmbeddings(
109
  api_key=HF_TOKEN,
110
  model_name="sentence-transformers/all-MiniLM-L6-v2"
111
  )
 
112
  except ImportError:
 
113
  try:
114
  from langchain_huggingface import HuggingFaceEmbeddings
115
  embeddings = HuggingFaceEmbeddings(
116
  model_name="sentence-transformers/all-MiniLM-L6-v2",
117
  cache_folder=CACHE_DIR
118
  )
119
- print("⚙️ Using HuggingFaceEmbeddings fallback")
120
  except Exception as e:
 
121
  raise RuntimeError(f"❌ Failed to load embeddings: {e}")
122
 
123
  if not texts:
124
- return FAISS.from_texts([""], embeddings) # dummy FAISS
 
125
 
126
  splitter = RecursiveCharacterTextSplitter(chunk_size=600, chunk_overlap=50)
127
  docs = splitter.create_documents(texts, metadatas=[{"source": DATASET}] * len(texts))
 
128
  return FAISS.from_documents(docs, embeddings)
129
 
130
  # ------------------------------------------------------------------ LLM
@@ -145,7 +152,7 @@ Question: {question}
145
  Answer:
146
  """)
147
 
148
- # ------------------------------------------------------------------ MAIN
149
  def ask_question(phone: str, question: str) -> Tuple[str, List]:
150
  intent = _detect_intent(question)
151
  company = _company_from_text(question)
@@ -155,24 +162,40 @@ def ask_question(phone: str, question: str) -> Tuple[str, List]:
155
  _save_chat(phone, question, answer)
156
  return answer, []
157
 
158
- vs = get_vectorstore()
159
- docs = vs.similarity_search(question, k=3)
 
 
 
 
 
160
  if not docs or docs[0].page_content.strip() == "":
161
  answer = _fallback_answer(company, intent if intent in ("money", "complain") else "default")
162
  _save_chat(phone, question, answer)
163
  return answer, []
164
 
165
- qa = RetrievalQA.from_chain_type(
166
- llm=get_llm(),
167
- retriever=vs.as_retriever(search_kwargs={"k": 3}),
168
- return_source_documents=True,
169
- chain_type_kwargs={"prompt": PROMPT}
170
- )
171
- result = qa({"query": question, "company": company})
172
- answer = result["result"].strip()
 
 
 
 
 
 
 
173
  _save_chat(phone, question, answer)
174
- return answer, result.get("source_documents", [])
175
 
 
176
  def _save_chat(phone: str, q: str, a: str) -> None:
177
- supabase.table("chat_memory").insert({"user_phone": phone, "role": "user", "message": q}).execute()
178
- supabase.table("chat_memory").insert({"user_phone": phone, "role": "assistant", "message": a}).execute()
 
 
 
 
1
  # rag.py – bullet-proof and container-safe
2
  from __future__ import annotations
3
+ import os, re, json, requests, traceback
4
  from functools import lru_cache
5
  from typing import List, Tuple
6
 
 
18
  SPLIT = "train"
19
  LIMIT = 500
20
  LLM_MODEL = "microsoft/DialoGPT-medium"
21
+
22
  SUPABASE_URL = os.getenv("SUPABASE_URL")
23
  SUPABASE_KEY = os.getenv("SUPABASE_KEY")
24
  HF_TOKEN = os.getenv("HF_TOKEN")
25
 
26
+ # ------------------------------------------------------------------ SAFE CACHE
27
  CACHE_DIR = os.getenv("HF_HOME", "/tmp/hf_cache")
28
  os.makedirs(CACHE_DIR, exist_ok=True)
29
  os.environ["TRANSFORMERS_CACHE"] = CACHE_DIR
 
32
 
33
  supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
34
 
35
+ # ------------------------------------------------------------------ INTENTS
36
  GREETING_RE = re.compile(r"\b(hi|hello|hey|good morning|good afternoon|good evening)\b", re.I)
37
  THANKS_RE = re.compile(r"\b(thank|thanks|appreciate)\b", re.I)
38
  BYE_RE = re.compile(r"\b(bye|goodbye|see you|later)\b", re.I)
 
105
  embeddings = None
106
 
107
  try:
108
+ # Primary attempt: use Inference API embeddings
109
  from langchain_huggingface import HuggingFaceInferenceAPIEmbeddings
110
  embeddings = HuggingFaceInferenceAPIEmbeddings(
111
  api_key=HF_TOKEN,
112
  model_name="sentence-transformers/all-MiniLM-L6-v2"
113
  )
114
+ print("✅ Using HuggingFaceInferenceAPIEmbeddings")
115
  except ImportError:
116
+ # Fallback: local embeddings (container-safe)
117
  try:
118
  from langchain_huggingface import HuggingFaceEmbeddings
119
  embeddings = HuggingFaceEmbeddings(
120
  model_name="sentence-transformers/all-MiniLM-L6-v2",
121
  cache_folder=CACHE_DIR
122
  )
123
+ print("⚙️ Using local HuggingFaceEmbeddings fallback")
124
  except Exception as e:
125
+ traceback.print_exc()
126
  raise RuntimeError(f"❌ Failed to load embeddings: {e}")
127
 
128
  if not texts:
129
+ print(" No dataset texts available; creating dummy FAISS index.")
130
+ return FAISS.from_texts([""], embeddings)
131
 
132
  splitter = RecursiveCharacterTextSplitter(chunk_size=600, chunk_overlap=50)
133
  docs = splitter.create_documents(texts, metadatas=[{"source": DATASET}] * len(texts))
134
+ print(f"🔹 Building FAISS index with {len(docs)} chunks")
135
  return FAISS.from_documents(docs, embeddings)
136
 
137
  # ------------------------------------------------------------------ LLM
 
152
  Answer:
153
  """)
154
 
155
+ # ------------------------------------------------------------------ MAIN LOGIC
156
  def ask_question(phone: str, question: str) -> Tuple[str, List]:
157
  intent = _detect_intent(question)
158
  company = _company_from_text(question)
 
162
  _save_chat(phone, question, answer)
163
  return answer, []
164
 
165
+ try:
166
+ vs = get_vectorstore()
167
+ docs = vs.similarity_search(question, k=3)
168
+ except Exception as e:
169
+ print(f"❌ Vector store retrieval failed: {e}")
170
+ docs = []
171
+
172
  if not docs or docs[0].page_content.strip() == "":
173
  answer = _fallback_answer(company, intent if intent in ("money", "complain") else "default")
174
  _save_chat(phone, question, answer)
175
  return answer, []
176
 
177
+ try:
178
+ qa = RetrievalQA.from_chain_type(
179
+ llm=get_llm(),
180
+ retriever=vs.as_retriever(search_kwargs={"k": 3}),
181
+ return_source_documents=True,
182
+ chain_type_kwargs={"prompt": PROMPT}
183
+ )
184
+ result = qa({"query": question, "company": company})
185
+ answer = result.get("result", "").strip() or _fallback_answer(company, "default")
186
+ docs_used = result.get("source_documents", [])
187
+ except Exception as e:
188
+ traceback.print_exc()
189
+ answer = _fallback_answer(company, "default")
190
+ docs_used = []
191
+
192
  _save_chat(phone, question, answer)
193
+ return answer, docs_used
194
 
195
+ # ------------------------------------------------------------------ SUPABASE LOGGING
196
  def _save_chat(phone: str, q: str, a: str) -> None:
197
+ try:
198
+ supabase.table("chat_memory").insert({"user_phone": phone, "role": "user", "message": q}).execute()
199
+ supabase.table("chat_memory").insert({"user_phone": phone, "role": "assistant", "message": a}).execute()
200
+ except Exception as e:
201
+ print(f"⚠ Chat log save failed: {e}")