vashu2425 commited on
Commit
2a65ba9
·
verified ·
1 Parent(s): 8bcbbf6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -45
app.py CHANGED
@@ -4,24 +4,23 @@ from langchain.embeddings import HuggingFaceEmbeddings
4
  from langchain.chains import RetrievalQA
5
  from langchain_community.vectorstores import FAISS
6
  from langchain_core.prompts import PromptTemplate
7
-
8
- from langchain_huggingface import HuggingFaceEmbeddings
9
  import time
10
  import translators as ts
11
  from huggingface_hub import hf_hub_download
12
- from dotenv import load_dotenv # Load .env locally
13
 
14
- # ================== CONFIGURATION ================== #
15
- # Load HF_TOKEN from Secrets or .env (for local development)
16
- load_dotenv()
17
- HF_TOKEN = os.getenv("HF_TOKEN")
18
 
 
 
19
  VECTORSTORE_REPO_ID = "vashu2425/bhagavad-geeta-faiss-vectordb"
20
  MODEL_REPO_ID = "mistralai/Mistral-7B-Instruct-v0.3"
21
 
 
22
  CUSTOM_PROMPT_TEMPLATE = """
23
  Use The Pieces Of Information Provided In The Context To Answer User's Question.
24
- If You Don't Know The Answer, Just Say "I Don't Have Information", except this do not say anything.
25
  Don't Try To Make Up An Answer. Don't Provide Anything Out Of The Given Context.
26
 
27
  Context: {context}
@@ -29,9 +28,9 @@ Question: {question}
29
 
30
  Start The Answer Directly., Please. The Answer Should Contain All 3 Contexts.
31
  Consider Yourself As God Krishna And Answer The Question Result Should Not Start With "Answer"
32
- """
33
 
34
- # ---------- Session Management ---------- #
35
  def initialize_session_states():
36
  session_defaults = {
37
  "messages": [],
@@ -39,16 +38,46 @@ def initialize_session_states():
39
  "show_predefined": True,
40
  "last_response": None,
41
  "translation_done": False,
42
- "last_prompt": None
43
  }
44
  for key, val in session_defaults.items():
45
  if key not in st.session_state:
46
  st.session_state[key] = val
47
 
48
- # ---------- Core Functionality ---------- #
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  def translate_text(text, dest_language="hi"):
50
  try:
51
- return ts.translate_text(text, to_language=dest_language, translator='google')
 
 
 
 
 
52
  except Exception as e:
53
  st.error(f"Translation failed: {str(e)}")
54
  return text
@@ -78,56 +107,70 @@ def get_vectorstore():
78
  def set_custom_prompt(custom_prompt_template):
79
  return PromptTemplate(template=custom_prompt_template, input_variables=["context", "question"])
80
 
81
- def load_llm():
82
  return HuggingFaceEndpoint(
83
- repo_id=MODEL_REPO_ID,
84
  temperature=0.5,
85
- huggingfacehub_api_token=HF_TOKEN,
86
  model_kwargs={"max_length": 512}
87
  )
88
 
 
 
 
 
 
 
 
 
89
  def handle_user_input(prompt, qa_chain):
90
  if prompt:
 
91
  if st.session_state.get("last_prompt") == prompt:
92
  return
 
 
93
  st.session_state.last_prompt = prompt
94
-
95
  with st.chat_message("user", avatar="🐿"):
96
  st.markdown(prompt)
97
  st.session_state.messages.append({"role": "user", "content": prompt})
98
 
99
  try:
 
100
  with st.chat_message("assistant", avatar="🪈"):
101
  response_placeholder = st.empty()
102
 
 
103
  response = qa_chain.invoke({"query": prompt})
104
  result = response["result"]
105
  source_documents = response["source_documents"]
106
 
 
107
  accumulated_text = ""
108
  for char in result:
109
  accumulated_text += char
110
  response_placeholder.markdown(f'<div class="english-text">{accumulated_text}</div>', unsafe_allow_html=True)
111
  time.sleep(0.01)
112
 
 
113
  st.session_state.messages.append({
114
  "role": "assistant",
115
  "content": f'<div class="english-text">{accumulated_text}</div>',
116
  "original": accumulated_text
117
  })
118
-
119
  st.session_state.last_response = accumulated_text
120
  st.session_state.show_predefined = False
121
  st.session_state.translation_done = False
122
 
123
  if "don't have information" not in result.lower():
124
  with st.expander("Source Documents"):
125
- for idx, doc in enumerate(source_documents, start=1):
126
- content = doc.page_content.replace('\t', ' ').replace('\n', ' ').strip()
127
- st.markdown(f"**Source {idx}**: {content[:500]}...")
128
 
129
  except Exception as e:
130
  st.error(f"Error: {str(e)}")
 
131
  if st.session_state.messages and st.session_state.messages[-1]["role"] == "assistant":
132
  st.session_state.messages.pop()
133
 
@@ -137,45 +180,146 @@ def handle_translation():
137
  if not st.session_state.get("translation_done", False):
138
  translated_text = translate_text(st.session_state.last_response, "hi")
139
 
 
140
  for msg in reversed(st.session_state.messages):
141
  if msg["role"] == "assistant":
142
  msg["content"] = f'<div class="hindi-text">{translated_text}</div>'
143
  break
144
 
145
  st.session_state.translation_done = True
146
- st.rerun()
147
-
148
  except Exception as e:
149
  st.error(f"Translation error: {str(e)}")
150
 
151
- def main():
152
- st.set_page_config(layout="wide")
153
- st.title("Ask Krishna! 🦚")
154
- st.markdown('<p class="hindi-text" style="color:#666666; font-size:20px;">शांति स्वीकृति से शुरू होती है</p>',
155
- unsafe_allow_html=True)
156
-
157
- initialize_session_states()
158
-
159
  for message in st.session_state.messages:
160
  with st.chat_message(message["role"], avatar="🐿" if message["role"] == "user" else "🪈"):
161
- content = message.get("original", message["content"])
162
  if "hindi-text" in message["content"]:
163
  st.markdown(message["content"], unsafe_allow_html=True)
164
  else:
165
  st.markdown(content)
166
 
167
- predefined_questions = [
168
- "Meaning of Dharma?", "What is the purpose of life?",
169
- "How to find inner peace?", "How can I be a better person?"
170
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
 
 
 
 
 
 
 
 
172
  if st.session_state.show_predefined:
173
- st.markdown("### Or, try one of these:")
174
- buttons = st.columns(len(predefined_questions))
175
- for idx, question in enumerate(predefined_questions):
176
- if buttons[idx].button(question, key=f"predefined_{idx}"):
177
- st.session_state.selected_question = question
178
- st.session_state.show_predefined = False
179
 
180
  prompt = st.chat_input("What's your curiosity?") or st.session_state.selected_question
181
  st.session_state.selected_question = None
@@ -183,7 +327,7 @@ def main():
183
  try:
184
  vectorstore = get_vectorstore()
185
  qa_chain = RetrievalQA.from_chain_type(
186
- llm=load_llm(),
187
  chain_type="stuff",
188
  retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
189
  return_source_documents=True,
@@ -205,5 +349,4 @@ def main():
205
  except Exception as e:
206
  st.error(f"Initialization error: {str(e)}")
207
 
208
- if __name__ == "__main__":
209
- main()
 
4
  from langchain.chains import RetrievalQA
5
  from langchain_community.vectorstores import FAISS
6
  from langchain_core.prompts import PromptTemplate
7
+ from langchain_community.llms import HuggingFaceEndpoint
 
8
  import time
9
  import translators as ts
10
  from huggingface_hub import hf_hub_download
 
11
 
12
+ # Set page layout to wide
13
+ st.set_page_config(layout="wide")
 
 
14
 
15
+ # ================== CONFIGURATION ================== #
16
+ HF_TOKEN = os.getenv("HF_TOKEN") # From Spaces secrets
17
  VECTORSTORE_REPO_ID = "vashu2425/bhagavad-geeta-faiss-vectordb"
18
  MODEL_REPO_ID = "mistralai/Mistral-7B-Instruct-v0.3"
19
 
20
+
21
  CUSTOM_PROMPT_TEMPLATE = """
22
  Use The Pieces Of Information Provided In The Context To Answer User's Question.
23
+ If You Don't Know The Answer, Just Say "I Don't Have Information",except this do not say anything.
24
  Don't Try To Make Up An Answer. Don't Provide Anything Out Of The Given Context.
25
 
26
  Context: {context}
 
28
 
29
  Start The Answer Directly., Please. The Answer Should Contain All 3 Contexts.
30
  Consider Yourself As God Krishna And Answer The Question Result Should Not Start With "Answer"
31
+ """ # Keep your template here
32
 
33
+ # ---------- Session Management Functions ---------- #
34
  def initialize_session_states():
35
  session_defaults = {
36
  "messages": [],
 
38
  "show_predefined": True,
39
  "last_response": None,
40
  "translation_done": False,
41
+ "last_prompt": None # Add this line
42
  }
43
  for key, val in session_defaults.items():
44
  if key not in st.session_state:
45
  st.session_state[key] = val
46
 
47
+ def render_chat_messages():
48
+ for message in st.session_state.messages:
49
+ with st.chat_message(message["role"], avatar="🐿" if message["role"] == "user" else "🪈"):
50
+ content = message["content"]
51
+ if "hindi-text" in content:
52
+ st.markdown(content, unsafe_allow_html=True)
53
+ else:
54
+ st.markdown(content)
55
+
56
+ def render_predefined_questions():
57
+ predefined_questions = [
58
+ "Meaning of Dharma?",
59
+ "What is the purpose of life?",
60
+ "How to find inner peace?",
61
+ "How can I be a better person?",
62
+ "What is the meaning of life?",
63
+ "How can I be a better friend?"
64
+ ]
65
+ st.markdown("### Or, try one of these:")
66
+ buttons = st.columns(len(predefined_questions))
67
+ for idx, question in enumerate(predefined_questions):
68
+ if buttons[idx].button(question, key=f"predefined_{idx}"):
69
+ st.session_state.selected_question = question
70
+ st.session_state.show_predefined = False
71
+
72
+ # ---------- Core Functionality Functions ---------- #
73
  def translate_text(text, dest_language="hi"):
74
  try:
75
+ # Use the updated translation method
76
+ return ts.translate_text(
77
+ text,
78
+ to_language=dest_language,
79
+ translator='google'
80
+ )
81
  except Exception as e:
82
  st.error(f"Translation failed: {str(e)}")
83
  return text
 
107
  def set_custom_prompt(custom_prompt_template):
108
  return PromptTemplate(template=custom_prompt_template, input_variables=["context", "question"])
109
 
110
+ def load_llm(huggingface_repo_id, hf_token):
111
  return HuggingFaceEndpoint(
112
+ repo_id=huggingface_repo_id,
113
  temperature=0.5,
114
+ huggingfacehub_api_token=hf_token,
115
  model_kwargs={"max_length": 512}
116
  )
117
 
118
+ def format_source_docs(source_documents):
119
+ formatted_docs = []
120
+ for idx, doc in enumerate(source_documents, start=1):
121
+ content = doc.page_content.replace('\t', ' ').replace('\n', ' ').strip()
122
+ formatted_doc = f"**Source {idx}** (Page {doc.metadata['page']}):\n\n{content[:500]}..."
123
+ formatted_docs.append(formatted_doc)
124
+ return "\n\n".join(formatted_docs)
125
+
126
  def handle_user_input(prompt, qa_chain):
127
  if prompt:
128
+ # Check if this prompt has already been processed
129
  if st.session_state.get("last_prompt") == prompt:
130
  return
131
+
132
+ # Store the current prompt to prevent reprocessing
133
  st.session_state.last_prompt = prompt
134
+
135
  with st.chat_message("user", avatar="🐿"):
136
  st.markdown(prompt)
137
  st.session_state.messages.append({"role": "user", "content": prompt})
138
 
139
  try:
140
+ # Add temporary assistant message
141
  with st.chat_message("assistant", avatar="🪈"):
142
  response_placeholder = st.empty()
143
 
144
+ # Process query and generate response
145
  response = qa_chain.invoke({"query": prompt})
146
  result = response["result"]
147
  source_documents = response["source_documents"]
148
 
149
+ # Build response incrementally
150
  accumulated_text = ""
151
  for char in result:
152
  accumulated_text += char
153
  response_placeholder.markdown(f'<div class="english-text">{accumulated_text}</div>', unsafe_allow_html=True)
154
  time.sleep(0.01)
155
 
156
+ # Update session state with final response
157
  st.session_state.messages.append({
158
  "role": "assistant",
159
  "content": f'<div class="english-text">{accumulated_text}</div>',
160
  "original": accumulated_text
161
  })
162
+
163
  st.session_state.last_response = accumulated_text
164
  st.session_state.show_predefined = False
165
  st.session_state.translation_done = False
166
 
167
  if "don't have information" not in result.lower():
168
  with st.expander("Source Documents"):
169
+ st.markdown(format_source_docs(source_documents))
 
 
170
 
171
  except Exception as e:
172
  st.error(f"Error: {str(e)}")
173
+ # Remove temporary assistant message on error
174
  if st.session_state.messages and st.session_state.messages[-1]["role"] == "assistant":
175
  st.session_state.messages.pop()
176
 
 
180
  if not st.session_state.get("translation_done", False):
181
  translated_text = translate_text(st.session_state.last_response, "hi")
182
 
183
+ # Update messages
184
  for msg in reversed(st.session_state.messages):
185
  if msg["role"] == "assistant":
186
  msg["content"] = f'<div class="hindi-text">{translated_text}</div>'
187
  break
188
 
189
  st.session_state.translation_done = True
190
+ st.rerun() # Corrected rerun method
191
+
192
  except Exception as e:
193
  st.error(f"Translation error: {str(e)}")
194
 
195
+ def render_chat_messages():
 
 
 
 
 
 
 
196
  for message in st.session_state.messages:
197
  with st.chat_message(message["role"], avatar="🐿" if message["role"] == "user" else "🪈"):
198
+ content = message.get("original", message["content"]) # Show original if available
199
  if "hindi-text" in message["content"]:
200
  st.markdown(message["content"], unsafe_allow_html=True)
201
  else:
202
  st.markdown(content)
203
 
204
+ def main():
205
+ st.markdown( """
206
+ <style>
207
+ @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+Devanagari:wght@400;700&display=swap');
208
+ .hindi-text {
209
+ font-family: 'Noto Sans Devanagari', sans-serif;
210
+ font-size: 16px;
211
+ line-height: 1.8;
212
+ direction: ltr;
213
+ text-align: left;
214
+ }
215
+
216
+ .english-text {
217
+ font-family: Arial, sans-serif;
218
+ font-size: 16px;
219
+ line-height: 1.6;
220
+ }
221
+
222
+ .translate-btn {
223
+ background-color: #4CAF50 !important;
224
+ color: white !important;
225
+ border-radius: 20px; /* Reduced from 25px */
226
+ padding: 6px 20px; /* Reduced from 8px 25px */
227
+ margin: 6px 0; /* Reduced from 10px 0 */
228
+ border: none;
229
+ transition: all 0.3s ease;
230
+ font-size: 14px; /* Added font-size control */
231
+ min-width: 120px; /* Added for better proportions */
232
+ }
233
+
234
+ .translate-btn:hover {
235
+ background-color: #45a049 !important;
236
+ transform: scale(1.03); /* Reduced from 1.05 */
237
+ }
238
+
239
+ .top-left-button {
240
+ position: auto;
241
+ top: 50px;
242
+ left: 20px;
243
+ z-index: 100;
244
+ padding: 10px 20px;
245
+ background-color: #e0162e;
246
+ color: white !important;
247
+ text-decoration: none !important;
248
+ border-radius: 50px;
249
+ margin-top: 10px;
250
+ font-size: 16px;
251
+ text-align: center;
252
+ }
253
+ .top-left-button:hover {
254
+ background-color: #f7525a;
255
+ }
256
+
257
+ /* Fullscreen styles */
258
+ body {
259
+ margin: 0;
260
+ padding: 0;
261
+ width: 100vw;
262
+ height: 100vh;
263
+ display: flex;
264
+ justify-content: center;
265
+ align-items: center;
266
+ background-color: #1e1e30; /* Change the background color to #1e1e30 */
267
+ }
268
+
269
+ [data-testid="stAppViewContainer"] > .main {
270
+ background-size: cover;
271
+ background-position: center center;
272
+ background-repeat: no-repeat;
273
+ background-attachment: local;
274
+ }
275
+
276
+ /* Header background */
277
+ [data-testid="stHeader"] {
278
+ background: #1e1e30;
279
+ }
280
+
281
+ /* Apply background color to the whole Streamlit app */
282
+ .stApp {
283
+ width: 100%;
284
+ max-width: 100vw;
285
+ display: flex;
286
+ justify-content: center;
287
+ align-items: flex-start;
288
+ padding: 20px;
289
+ background-color: #1e1e30; /* This will apply the background color to the entire app */
290
+ }
291
+
292
+ .custom-paragraph {
293
+ font-size: 20px !important;
294
+ line-height: 0.2;
295
+ color: #666666;
296
+ }
297
+
298
+ /* Apply background color to stBottomBlockContainer */
299
+ [data-testid="stBottomBlockContainer"] {
300
+ background-color: #1e1e30; /* Set the same color for bottom block */
301
+ }
302
+
303
+ /* Hover effect for textarea (optional) */
304
+ .stTextArea>div>textarea:hover {
305
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3); /* Change shadow on hover */
306
+ </style>
307
+ <a href="https://iskconmangaluru.com/wp-content/uploads/2021/04/English-Bhagavad-gita-His-Divine-Grace-AC-Bhaktivedanta-Swami-Prabhupada.pdf" target="_blank" class="top-left-button">
308
+ Source Bhagavad Gita PDF
309
+ </a>
310
+ """,
311
+ unsafe_allow_html=True
312
+ )
313
 
314
+ st.title("Ask Krishna! 🦚")
315
+ st.markdown('<p class="hindi-text" style="color:#666666; font-size:20px;">शांति स्वीकृति से शुरू होती है</p>',
316
+ unsafe_allow_html=True)
317
+
318
+ initialize_session_states()
319
+ render_chat_messages()
320
+
321
  if st.session_state.show_predefined:
322
+ render_predefined_questions()
 
 
 
 
 
323
 
324
  prompt = st.chat_input("What's your curiosity?") or st.session_state.selected_question
325
  st.session_state.selected_question = None
 
327
  try:
328
  vectorstore = get_vectorstore()
329
  qa_chain = RetrievalQA.from_chain_type(
330
+ llm=load_llm(MODEL_REPO_ID, HF_TOKEN),
331
  chain_type="stuff",
332
  retriever=vectorstore.as_retriever(search_kwargs={"k": 3}),
333
  return_source_documents=True,
 
349
  except Exception as e:
350
  st.error(f"Initialization error: {str(e)}")
351
 
352
+ if __name__ == "__main__"