euracle commited on
Commit
923e115
·
verified ·
1 Parent(s): fe3ce25

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -242
app.py CHANGED
@@ -10,272 +10,98 @@ from langchain.chains import RetrievalQA
10
  from langchain.document_loaders import PyPDFLoader
11
  from langchain.text_splitter import RecursiveCharacterTextSplitter
12
  from langchain.chains import LLMChain
13
-
14
- # Set persistent storage path
15
- PERSISTENT_DIR = "vector_db"
16
-
17
- def initialize_vector_db():
18
- # Check if vector database already exists in persistent storage
19
- if os.path.exists(PERSISTENT_DIR) and os.listdir(PERSISTENT_DIR):
20
- embeddings = HuggingFaceEmbeddings()
21
- vector_db = Chroma(persist_directory=PERSISTENT_DIR, embedding_function=embeddings)
22
- return None, vector_db
23
-
24
- base_dir = os.path.dirname(os.path.abspath(__file__))
25
- pdf_files = [f for f in os.listdir(base_dir) if f.endswith('.pdf')]
26
- loaders = [PyPDFLoader(os.path.join(base_dir, fn)) for fn in pdf_files]
27
-
28
- documents = []
29
- for loader in loaders:
30
- documents.extend(loader.load())
31
-
32
- text_splitter = RecursiveCharacterTextSplitter(
33
- chunk_size=1000,
34
- chunk_overlap=200,
35
- length_function=len,
36
- separators=["\n\n", "\n", " ", ""]
37
- )
38
- texts = text_splitter.split_documents(documents)
39
-
40
- embeddings = HuggingFaceEmbeddings()
41
- vector_db = Chroma.from_documents(
42
- texts,
43
- embeddings,
44
- persist_directory=PERSISTENT_DIR
45
  )
46
- vector_db.persist()
47
- return documents, vector_db
48
-
49
- # System instructions for the LLM
50
- system_prompt = """You are an expert organic farming consultant with specialization in Agro-Homeopathy. When providing suggestions and remedies:
51
- 1. Always specify medicine potency as 6c unless the uploaded text mentions some other value explicitly
52
- 3. Provide comprehensive diagnosis and treatment advice along with organic farming best practices applicable in the given context
53
- 4. Base recommendations on homeopathic and organic farming principles
54
- """
55
-
56
- api_key1 = os.getenv("api_key")
57
-
58
- start_time = time.time()
59
- st.set_page_config(page_title="Dr. Radha: The Agro-Homeopath", page_icon="🚀", layout="wide")
60
-
61
- # CSS for dark green background and white text
62
- st.markdown("""
63
- <style>
64
- /* Set background color for entire app */
65
- .stApp {
66
- background-color: #1B4D3E !important;
67
- color: white !important;
68
- }
69
-
70
- /* Style input fields */
71
- .stTextInput>div>div>input {
72
- color: black !important;
73
- background-color: rgba(255,255,255,0.1) !important;
74
- }
75
-
76
- /* Style buttons */
77
- .stButton>button {
78
- color: black !important;
79
- background-color: yellow !important;
80
- }
81
-
82
- }
83
- </style>
84
- """, unsafe_allow_html=True)
85
-
86
- st.markdown("""
87
- <style>
88
- #the-title {
89
- text-align: center;
90
- font-size: 24px;
91
- color: white;
92
- }
93
- </style>
94
- """, unsafe_allow_html=True)
95
-
96
- st.title("🌿 Dr. Radha: AI-Powered Organic Farming Consultant")
97
- st.subheader("Specializing in Agro-Homeopathy | Free Consultation")
98
-
99
- # Add information request message
100
- st.markdown("""
101
- Please provide complete details about the issue, including:
102
- - Detailed description of plant problem
103
- - Current location, temperature & weather conditions
104
- """)
105
-
106
- human_image = "human.png"
107
- robot_image = "bot.jpg"
108
-
109
- # Set up Groq API with temperature 0.7
110
- llm = ChatGroq(
111
- api_key=api_key1,
112
- max_tokens=None,
113
- timeout=None,
114
- max_retries=2,
115
- temperature=0.7,
116
- model="llama-3.1-70b-versatile"
117
- )
118
-
119
- embeddings = HuggingFaceEmbeddings()
120
- end_time = time.time()
121
- print(f"Setting up Groq LLM & Embeddings took {end_time - start_time:.4f} seconds")
122
-
123
- # Initialize session state
124
- if "documents" not in st.session_state:
125
- st.session_state["documents"] = None
126
- if "vector_db" not in st.session_state:
127
- st.session_state["vector_db"] = None
128
- if "query" not in st.session_state:
129
- st.session_state["query"] = ""
130
-
131
- start_time = time.time()
132
- if st.session_state["documents"] is None or st.session_state["vector_db"] is None:
133
- with st.spinner("Loading data..."):
134
- documents, vector_db = initialize_vector_db()
135
- st.session_state["documents"] = documents
136
- st.session_state["vector_db"] = vector_db
137
- else:
138
- documents = st.session_state["documents"]
139
- vector_db = st.session_state["vector_db"]
140
 
141
- end_time = time.time()
142
- print(f"Loading and processing PDFs & vector database took {end_time - start_time:.4f} seconds")
143
 
144
- start_time = time.time()
145
- retriever = vector_db.as_retriever()
 
 
 
146
 
147
- prompt_template = """As an expert organic farming consultant with specialization in Agro-Homeopathy, analyze the following context and question to provide a clear, structured response.
 
 
 
 
148
 
149
- Context: {context}
150
-
151
- Question: {question}
152
-
153
- Provide your response in the following format:
154
- Analysis: Analyze the described plant condition
155
- Treatment: Recommend relevant organic farming principles and specific homeopathic medicine(s) with exact potency and repetition frequency. Suggest a maximum of 4 medicines in the order of relevance for any single problem.
156
- Instructions for Use:
157
- Small Plots or Gardens: Make sure your dispensing equipment is not contaminated with
158
- other chemicals or fertilisers as these may antidote the energetic effects of the treatment—
159
- rinse well with hot water before use if necessary. Add one pill to each 200 ml of water, shake
160
- vigorously, and then spray or water your plants. Avoid using other chemicals or fertilisers for
161
- 10 days following treatment so that the energetic effects of the treatment are not antidoted.
162
- (One vial of 100 pills makes 20 litres. Plants remain insect or disease free for up to 3 months
163
- following one treatment.)
164
- Large Plots or Farms: Add the remedy to water and apply with the dispensing device of
165
- your choice: watering can, backpack sprayer, boomspray, reticulation systems (add to tanks
166
- or pumps). Make sure your dispensing equipment is not contaminated with other chemicals
167
- or fertilisers as these may antidote the energetic effects of the treatment—rinse with hot
168
- water or steam clean before use if necessary. Avoid using other chemicals or fertilisers for
169
- 10 days following treatment.
170
- Dosage rates are approximate and may vary according to different circumstances and
171
- experiences. Suggested doses are:
172
- 10 pills or 10ml/10 litre on small areas,
173
- 500 pills or 125ml/500l per hectare,
174
- 1000 pills or 250ml/500l per hectare,
175
- 2500 pills or 500ml/500l per hectare,
176
- Add pills or liquid to your water and mix (with a stick if necessary for large containers).
177
-
178
- Recommendations: Provide couple of key pertinent recommendations based on the query
179
-
180
- Remember to maintain a professional, clear tone and ensure all medicine recommendations include specific potency.
181
-
182
- Answer:"""
183
-
184
- # Create the QA chain with correct variables
185
  qa = RetrievalQA.from_chain_type(
186
  llm=llm,
187
  chain_type="stuff",
188
  retriever=retriever,
 
189
  chain_type_kwargs={
190
  "prompt": PromptTemplate(
191
  template=prompt_template,
192
- input_variables=["context", "question"]
193
  )
194
  }
195
  )
196
 
197
- # Create a separate LLMChain for fallback
198
- fallback_template = """As an expert organic farming consultant with specialization in Agro-Homeopathy, analyze the following context and question to provide a clear, structured response.
199
-
200
- Question: {question}
201
-
202
- Format your response as follows:
203
- Analysis: Analyze the described plant condition
204
- Treatment: Recommend relevant organic farming principles and specific homeopathic medicine(s) with exact potency and repetition frequency. Suggest a maximum of 4 medicines in the order of relevance for any single problem.
205
- Instructions for Use:
206
- Small Plots or Gardens: Make sure your dispensing equipment is not contaminated with
207
- other chemicals or fertilisers as these may antidote the energetic effects of the treatment—
208
- rinse well with hot water before use if necessary. Add one pill to each 200 ml of water, shake
209
- vigorously, and then spray or water your plants. Avoid using other chemicals or fertilisers for
210
- 10 days following treatment so that the energetic effects of the treatment are not antidoted.
211
- (One vial of 100 pills makes 20 litres. Plants remain insect or disease free for up to 3 months
212
- following one treatment.)
213
- Large Plots or Farms: Add the remedy to water and apply with the dispensing device of
214
- your choice: watering can, backpack sprayer, boomspray, reticulation systems (add to tanks
215
- or pumps). Make sure your dispensing equipment is not contaminated with other chemicals
216
- or fertilisers as these may antidote the energetic effects of the treatment—rinse with hot
217
- water or steam clean before use if necessary. Avoid using other chemicals or fertilisers for
218
- 10 days following treatment.
219
- Dosage rates are approximate and may vary according to different circumstances and
220
- experiences. Suggested doses are:
221
- 10 pills or 10ml/10 litre on small areas
222
- 500 pills or 125ml/500l per hectare
223
- 1000 pills or 250ml/500l per hectare
224
- 2500 pills or 500ml/500l per hectare
225
- Add pills or liquid to your water and mix (with a stick if necessary for large containers).
226
-
227
- Recommendations: Provide couple of key pertinent recommendations based on the query
228
-
229
- Maintain a professional tone and ensure all medicine recommendations include specific potency.
230
-
231
- Answer:"""
232
-
233
- fallback_prompt = PromptTemplate(template=fallback_template, input_variables=["question"])
234
- fallback_chain = LLMChain(llm=llm, prompt=fallback_prompt)
235
-
236
- chat_container = st.container()
237
-
238
- st.markdown("""
239
- <style>
240
- .stButton>button {
241
- color: black !important;
242
- background-color: yellow !important;
243
- }
244
- </style>
245
- """, unsafe_allow_html=True)
246
-
247
- with st.form(key='query_form'):
248
- query = st.text_input("Ask your question:", value="")
249
- submit_button = st.form_submit_button(label='Submit')
250
-
251
- end_time = time.time()
252
- #print(f"Setting up retrieval chain took {end_time - start_time:.4f} seconds")
253
- start_time = time.time()
254
 
 
255
  if submit_button and query:
256
  with st.spinner("Generating response..."):
257
- result = qa({"query": query})
 
 
 
 
 
 
 
 
 
 
 
258
  if result['result'].strip() == "":
259
- # If no result from PDF, use fallback chain
260
  fallback_result = fallback_chain.run(query)
261
  response = fallback_result
262
  else:
263
  response = result['result']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
 
265
- col1, col2 = st.columns([1, 10])
266
- with col1:
267
- st.image(human_image, width=80)
268
- with col2:
269
- st.markdown(f"{query}")
270
- col1, col2 = st.columns([1, 10])
271
- with col1:
272
- st.image(robot_image, width=80)
273
- with col2:
274
- st.markdown(f"{response}")
275
-
276
  st.markdown("---")
277
-
278
  st.session_state["query"] = ""
279
-
280
- end_time = time.time()
281
- print(f"Actual query took {end_time - start_time:.4f} seconds")
 
10
  from langchain.document_loaders import PyPDFLoader
11
  from langchain.text_splitter import RecursiveCharacterTextSplitter
12
  from langchain.chains import LLMChain
13
+ from langchain.memory import ConversationBufferMemory
14
+
15
+ # Initialize session state for chat history and memory
16
+ if "chat_history" not in st.session_state:
17
+ st.session_state.chat_history = []
18
+ if "memory" not in st.session_state:
19
+ st.session_state.memory = ConversationBufferMemory(
20
+ memory_key="chat_history",
21
+ return_messages=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ # Add sidebar
25
+ st.sidebar.title("Chat History")
26
 
27
+ # Add Clear Session button in sidebar
28
+ if st.sidebar.button("Clear Session"):
29
+ st.session_state.chat_history = []
30
+ st.session_state.memory.clear()
31
+ st.experimental_rerun()
32
 
33
+ # Display chat history in sidebar
34
+ for i, chat in enumerate(st.session_state.chat_history):
35
+ st.sidebar.text(f"Q{i+1}: {chat['question']}")
36
+ if st.sidebar.button(f"Go to Q{i+1}", key=f"btn_{i}"):
37
+ st.session_state.query = chat['question']
38
 
39
+ # Update the QA chain to include memory
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  qa = RetrievalQA.from_chain_type(
41
  llm=llm,
42
  chain_type="stuff",
43
  retriever=retriever,
44
+ memory=st.session_state.memory,
45
  chain_type_kwargs={
46
  "prompt": PromptTemplate(
47
  template=prompt_template,
48
+ input_variables=["context", "question", "chat_history"]
49
  )
50
  }
51
  )
52
 
53
+ # Update fallback chain to include memory
54
+ fallback_chain = LLMChain(
55
+ llm=llm,
56
+ prompt=fallback_prompt,
57
+ memory=st.session_state.memory
58
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ # Update the form submission handling
61
  if submit_button and query:
62
  with st.spinner("Generating response..."):
63
+ # Add query to chat history
64
+ st.session_state.chat_history.append({
65
+ "question": query,
66
+ "timestamp": time.time()
67
+ })
68
+
69
+ # Get response with memory context
70
+ result = qa({
71
+ "query": query,
72
+ "chat_history": st.session_state.memory.chat_memory
73
+ })
74
+
75
  if result['result'].strip() == "":
 
76
  fallback_result = fallback_chain.run(query)
77
  response = fallback_result
78
  else:
79
  response = result['result']
80
+
81
+ # Store the interaction in memory
82
+ st.session_state.memory.save_context(
83
+ {"input": query},
84
+ {"output": response}
85
+ )
86
+
87
+ # Display chat messages
88
+ for chat in st.session_state.chat_history:
89
+ col1, col2 = st.columns([1, 10])
90
+ with col1:
91
+ st.image(human_image, width=80)
92
+ with col2:
93
+ st.markdown(f"{chat['question']}")
94
+
95
+ col1, col2 = st.columns([1, 10])
96
+ with col1:
97
+ st.image(robot_image, width=80)
98
+ with col2:
99
+ if chat['question'] == query:
100
+ st.markdown(f"{response}")
101
+ else:
102
+ # Retrieve previous response from memory
103
+ prev_response = st.session_state.memory.load_memory_variables({})
104
+ st.markdown(f"{prev_response}")
105
 
 
 
 
 
 
 
 
 
 
 
 
106
  st.markdown("---")
 
107
  st.session_state["query"] = ""