Daemontatox commited on
Commit
c09fdef
·
verified ·
1 Parent(s): db55e80

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +150 -12
app.py CHANGED
@@ -1,4 +1,4 @@
1
- import subprocess
2
  import os
3
  import torch
4
  from dotenv import load_dotenv
@@ -72,6 +72,20 @@ Chat History:
72
 
73
  Current Question: {question}
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  Rewritten question:
76
  """
77
 
@@ -82,7 +96,24 @@ Question: {question}
82
  Retrieved Context: {context}
83
  Chat History: {chat_history}
84
 
85
- Reasoning:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  """
87
 
88
  response_template = """
@@ -100,6 +131,12 @@ Chat History:
100
  Current Question:
101
  {question}
102
 
 
 
 
 
 
 
103
  Response:
104
  """
105
 
@@ -160,8 +197,6 @@ retriever = db.as_retriever(
160
  )
161
 
162
  # Initialize LLM
163
-
164
-
165
  llm = ChatOpenAI(
166
  model="Qwen/Qwen2.5-72B-Instruct",
167
  temperature=0,
@@ -172,6 +207,7 @@ llm = ChatOpenAI(
172
  base_url="https://api-inference.huggingface.co/v1/",
173
  stream=True,
174
  )
 
175
  # Initialize chains
176
  query_rewrite_chain = LLMChain(
177
  llm=llm,
@@ -197,9 +233,9 @@ async def astream_processor(chain, inputs: dict) -> AsyncGenerator[str, None]:
197
  async for chunk in chain.astream(inputs):
198
  if isinstance(chunk, dict):
199
  content = chunk.get('content', '')
200
- yield content
201
  else:
202
- yield str(chunk)
 
203
  except Exception as e:
204
  logger.error(f"Error in stream processing: {e}")
205
  yield ""
@@ -207,17 +243,18 @@ async def astream_processor(chain, inputs: dict) -> AsyncGenerator[str, None]:
207
  async def process_stream_async(stream_queue: asyncio.Queue, history: List[List[str]]) -> AsyncGenerator[List[List[str]], None]:
208
  """Handle streaming response processing"""
209
  current_response = ""
 
210
  try:
211
  while True:
212
  chunk = await stream_queue.get()
213
  if chunk is None:
214
  break
215
 
216
- chunk_text = chunk.get('content', '') if isinstance(chunk, dict) else str(chunk)
217
- current_response += chunk_text
218
  new_history = history.copy()
219
  new_history[-1][1] = current_response
220
  yield new_history
 
221
  stream_queue.task_done()
222
  except asyncio.CancelledError:
223
  logger.info("Stream processing cancelled")
@@ -231,6 +268,8 @@ async def rewrite_query(question: str, formatted_history: str) -> str:
231
  question=question,
232
  chat_history=formatted_history
233
  )
 
 
234
  return rewritten_question.strip()
235
  except Exception as e:
236
  logger.error(f"Error in query rewriting: {e}")
@@ -239,21 +278,120 @@ async def rewrite_query(question: str, formatted_history: str) -> str:
239
  async def perform_chain_of_thought(question: str, context: str, chat_history: str) -> Dict[str, str]:
240
  """Execute chain of thought reasoning"""
241
  try:
242
- reasoning = "..."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  cot_analysis = await cot_chain.arun(
244
  question=question,
245
  context=context,
246
  chat_history=chat_history,
247
  reasoning=reasoning
248
  )
249
- return {"reasoning": reasoning, "cot_analysis": cot_analysis}
 
 
 
 
250
  except Exception as e:
251
  logger.error(f"Error in chain of thought reasoning: {e}")
252
- return {"reasoning": "", "cot_analysis": ""}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
  chat_history = ChatHistory()
255
 
256
- # The rest remains the same for Gradio components.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
 
258
  # Gradio Interface
259
  with gr.Blocks(theme='Hev832/Applio') as iface:
 
1
+ import subprocess
2
  import os
3
  import torch
4
  from dotenv import load_dotenv
 
72
 
73
  Current Question: {question}
74
 
75
+ Let's analyze this systematically:
76
+
77
+ 1. First, let's identify the core elements of the question:
78
+ - What is the main topic or action being asked about?
79
+ - What specific Mawared HR features or functions are relevant?
80
+ - What contextual information from chat history might be important?
81
+
82
+ 2. Then, consider any implicit context from the chat history:
83
+ - Are there any previous questions that provide relevant context?
84
+ - Has the user mentioned specific scenarios or requirements before?
85
+ - Are there any unresolved points from previous interactions?
86
+
87
+ 3. Based on this analysis, let's rewrite the question to be more specific and contextual.
88
+
89
  Rewritten question:
90
  """
91
 
 
96
  Retrieved Context: {context}
97
  Chat History: {chat_history}
98
 
99
+ 1. Understanding the Query:
100
+ - Core Request: What is the user trying to achieve?
101
+ - System Components: Which Mawared HR modules are involved?
102
+ - User Context: What do we know about the user's situation?
103
+
104
+ 2. Analyzing Available Information:
105
+ - Relevant Context: What specific information from our knowledge base applies?
106
+ - Historical Context: How does the chat history inform this query?
107
+ - Information Gaps: What additional details might we need?
108
+
109
+ 3. Solution Formulation:
110
+ - Key Steps: What actions are needed to address this query?
111
+ - Potential Challenges: What issues should we anticipate?
112
+ - Additional Considerations: What else should the user know?
113
+
114
+ Based on this analysis, let's structure our response to be clear, accurate, and helpful.
115
+
116
+ Reasoning: {reasoning}
117
  """
118
 
119
  response_template = """
 
131
  Current Question:
132
  {question}
133
 
134
+ Please provide a clear, structured response that:
135
+ 1. Directly addresses the user's question
136
+ 2. Includes specific steps or instructions where relevant
137
+ 3. Maintains a professional yet friendly tone
138
+ 4. References only information from the provided context
139
+
140
  Response:
141
  """
142
 
 
197
  )
198
 
199
  # Initialize LLM
 
 
200
  llm = ChatOpenAI(
201
  model="Qwen/Qwen2.5-72B-Instruct",
202
  temperature=0,
 
207
  base_url="https://api-inference.huggingface.co/v1/",
208
  stream=True,
209
  )
210
+
211
  # Initialize chains
212
  query_rewrite_chain = LLMChain(
213
  llm=llm,
 
233
  async for chunk in chain.astream(inputs):
234
  if isinstance(chunk, dict):
235
  content = chunk.get('content', '')
 
236
  else:
237
+ content = str(chunk)
238
+ yield content
239
  except Exception as e:
240
  logger.error(f"Error in stream processing: {e}")
241
  yield ""
 
243
  async def process_stream_async(stream_queue: asyncio.Queue, history: List[List[str]]) -> AsyncGenerator[List[List[str]], None]:
244
  """Handle streaming response processing"""
245
  current_response = ""
246
+
247
  try:
248
  while True:
249
  chunk = await stream_queue.get()
250
  if chunk is None:
251
  break
252
 
253
+ current_response += chunk
 
254
  new_history = history.copy()
255
  new_history[-1][1] = current_response
256
  yield new_history
257
+
258
  stream_queue.task_done()
259
  except asyncio.CancelledError:
260
  logger.info("Stream processing cancelled")
 
268
  question=question,
269
  chat_history=formatted_history
270
  )
271
+ logger.info(f"Original question: {question}")
272
+ logger.info(f"Rewritten question: {rewritten_question}")
273
  return rewritten_question.strip()
274
  except Exception as e:
275
  logger.error(f"Error in query rewriting: {e}")
 
278
  async def perform_chain_of_thought(question: str, context: str, chat_history: str) -> Dict[str, str]:
279
  """Execute chain of thought reasoning"""
280
  try:
281
+ reasoning = await llm.invoke(
282
+ f"""
283
+ Let's think through this Mawared HR query:
284
+
285
+ Question: {question}
286
+ Context: {context}
287
+
288
+ 1. Core Request Analysis:
289
+ - What specifically is the user asking about?
290
+ - What Mawared HR components are involved?
291
+
292
+ 2. Context Relevance:
293
+ - How does the provided context relate to the question?
294
+ - What specific information can we use?
295
+
296
+ 3. Solution Formation:
297
+ - What are the key points we need to address?
298
+ - What specific steps or information should we provide?
299
+
300
+ Reasoning:
301
+ """
302
+ )
303
+
304
  cot_analysis = await cot_chain.arun(
305
  question=question,
306
  context=context,
307
  chat_history=chat_history,
308
  reasoning=reasoning
309
  )
310
+
311
+ return {
312
+ "reasoning": reasoning,
313
+ "cot_analysis": cot_analysis
314
+ }
315
  except Exception as e:
316
  logger.error(f"Error in chain of thought reasoning: {e}")
317
+ return {
318
+ "reasoning": "Error in reasoning process",
319
+ "cot_analysis": "Error in chain of thought process"
320
+ }
321
+
322
+ async def generate_streaming_response(question: str, context: str, chat_history: str, cot_analysis: str) -> AsyncGenerator[str, None]:
323
+ """Generate streaming response using all available context"""
324
+ try:
325
+ inputs = {
326
+ "question": question,
327
+ "context": context,
328
+ "chat_history": chat_history,
329
+ "cot_analysis": cot_analysis
330
+ }
331
+
332
+ async for chunk in astream_processor(response_chain, inputs):
333
+ if chunk:
334
+ yield chunk
335
+ except Exception as e:
336
+ logger.error(f"Error in response generation: {e}")
337
+ yield "I apologize, but I encountered an error while generating the response."
338
 
339
  chat_history = ChatHistory()
340
 
341
+ async def ask_question_gradio(question: str, history: List[List[str]]) -> AsyncGenerator[tuple, None]:
342
+ """Main function to handle questions and generate responses"""
343
+ try:
344
+ if history is None:
345
+ history = []
346
+
347
+ chat_history.add_message("user", question)
348
+ formatted_history = chat_history.get_formatted_history()
349
+
350
+ rewritten_question = await rewrite_query(question, formatted_history)
351
+ context_docs = await asyncio.to_thread(retriever.get_relevant_documents, rewritten_question)
352
+ context = "\n".join([doc.page_content for doc in context_docs])
353
+
354
+ cot_results = await perform_chain_of_thought(rewritten_question, context, formatted_history)
355
+
356
+ history.append([question, ""])
357
+ stream_queue = asyncio.Queue()
358
+
359
+ async def stream_manager():
360
+ try:
361
+ async for chunk in generate_streaming_response(
362
+ rewritten_question,
363
+ context,
364
+ formatted_history,
365
+ cot_results["cot_analysis"]
366
+ ):
367
+ if chunk:
368
+ await stream_queue.put(chunk)
369
+ await stream_queue.put(None)
370
+ except Exception as e:
371
+ logger.error(f"Streaming error: {e}")
372
+ await stream_queue.put(None)
373
+
374
+ asyncio.create_task(stream_manager())
375
+
376
+ response = ""
377
+ async for updated_history in process_stream_async(stream_queue, history):
378
+ response = updated_history[-1][1]
379
+ yield "", updated_history
380
+
381
+ chat_history.add_message("assistant", response)
382
+
383
+ except Exception as e:
384
+ logger.error(f"Error during question processing: {e}")
385
+ logger.exception("Detailed error:")
386
+ if not history:
387
+ history = []
388
+ history.append([question, "An error occurred. Please try again later."])
389
+ yield "", history
390
+
391
+ def clear_chat():
392
+ """Clear chat history"""
393
+ chat_history.clear()
394
+ return [], ""
395
 
396
  # Gradio Interface
397
  with gr.Blocks(theme='Hev832/Applio') as iface: