Shriharsh commited on
Commit
8907b38
·
verified ·
1 Parent(s): 428a54e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -49
app.py CHANGED
@@ -1,8 +1,8 @@
1
- import logging
2
  import gradio as gr
3
  from transformers import pipeline
4
  from sentence_transformers import SentenceTransformer, util
5
  import PyPDF2
 
6
  import os
7
 
8
  # Load models
@@ -19,7 +19,7 @@ def extract_text_from_pdf(file_path):
19
  return text
20
 
21
  # Find the most relevant section in the document
22
- def find_relevant_section(query, sections, section_embeddings):
23
  stopwords = {"and", "the", "is", "for", "to", "a", "an", "of", "in", "on", "at", "with", "by", "it", "as", "so", "what"}
24
 
25
  # Semantic search
@@ -31,39 +31,40 @@ def find_relevant_section(query, sections, section_embeddings):
31
 
32
  SIMILARITY_THRESHOLD = 0.4
33
  if similarity_score >= SIMILARITY_THRESHOLD:
34
- log_message(f"Found relevant section using embeddings for query: {query}")
35
- return best_section
36
 
37
- log_message(f"Low similarity ({similarity_score}). Falling back to keyword search.")
38
 
39
  # Keyword-based fallback search with stopword filtering
40
- query_words = {word for word in sections:
 
41
  section_words = {word for word in section.lower().split() if word not in stopwords}
42
  common_words = query_words.intersection(section_words)
43
  if len(common_words) >= 2:
44
- log_message(f"Keyword match found for query: {query} with common words: {common_words}")
45
- return section
46
 
47
- log_message(f"No good keyword match found. Returning default fallback response.")
48
- return "I don’t have enough information to answer that."
49
 
50
  # Process the uploaded file with detailed logging
51
- def process_file(file, state):
52
  if file is None:
53
- log_message("No file uploaded.")
54
- return [("Bot", "Please upload a file.")], state
55
 
56
  file_path = file.name
57
  if file_path.lower().endswith(".pdf"):
58
- log_message(f"Uploaded PDF file: {file_path}")
59
  text = extract_text_from_pdf(file_path)
60
  elif file_path.lower().endswith(".txt"):
61
- log_message(f"Uploaded TXT file: {file_path}")
62
  with open(file_path, 'r', encoding='utf-8') as f:
63
  text = f.read()
64
  else:
65
- log_message(f"Unsupported file format: {file_path}")
66
- return [("Bot", "Unsupported file format. Please upload a PDF or TXT file.")], state
67
 
68
  sections = text.split('\n\n')
69
  section_embeddings = embedder.encode(sections, convert_to_tensor=True)
@@ -74,27 +75,27 @@ def process_file(file, state):
74
  state['feedback_count'] = 0
75
  state['mode'] = 'waiting_for_query'
76
  state['chat_history'] = [("Bot", "File processed. You can now ask questions.")]
77
- log_message(f"Processed file: {file_path}")
78
- return state['chat_history'], state
79
 
80
  # Handle user input (queries and feedback)
81
- def handle_input(user_input, state):
82
  if state['mode'] == 'waiting_for_upload':
83
  state['chat_history'].append(("Bot", "Please upload a file first."))
84
- log_message("User attempted to interact without uploading a file.")
85
- return state['chat_history'], state
86
  elif state['mode'] == 'waiting_for_query':
87
  if user_input.lower() == "exit":
88
- log_message("User entered 'exit'. Ending session.")
89
  state['mode'] = 'exited'
90
  state['chat_history'].append(("User", "exit"))
91
  state['chat_history'].append(("Bot", "Session ended. You can download the log file."))
92
- return state['chat_history'], state
93
 
94
  query = user_input
95
  state['current_query'] = query
96
  state['feedback_count'] = 0
97
- context = find_relevant_section(query, state['sections'], state['section_embeddings'])
98
  if context == "I don’t have enough information to answer that.":
99
  answer = context
100
  else:
@@ -105,45 +106,45 @@ def handle_input(user_input, state):
105
  state['chat_history'].append(("User", query))
106
  state['chat_history'].append(("Bot", f"Answer: {answer}\nPlease provide feedback: good, too vague, not helpful."))
107
  # Log the query and initial answer here:
108
- log_message(f"Query: {query}, Answer: {answer}")
109
  elif state['mode'] == 'waiting_for_feedback':
110
  if user_input.lower() == "exit":
111
- log_message("User entered 'exit'. Ending session.")
112
  state['mode'] = 'exited'
113
  state['chat_history'].append(("User", "exit"))
114
  state['chat_history'].append(("Bot", "Session ended. You can download the log file."))
115
- return state['chat_history'], state
116
 
117
  feedback = user_input.lower()
118
  state['chat_history'].append(("User", feedback))
119
- log_message(f"Feedback: {feedback}")
120
  if feedback == "good" or state['feedback_count'] >= 2:
121
  state['mode'] = 'waiting_for_query'
122
  if feedback == "good":
123
  state['chat_history'].append(("Bot", "Thank you for your feedback. You can ask another question."))
124
- log_message("Feedback accepted as 'good'. Waiting for next query.")
125
  else:
126
  state['chat_history'].append(("Bot", "Maximum feedback iterations reached. You can ask another question."))
127
- log_message("Max feedback iterations reached. Waiting for next query.")
128
  else:
129
  query = state['current_query']
130
- context = find_relevant_section(query, state['sections'], state['section_embeddings'])
131
  if feedback == "too vague":
132
  adjusted_answer = f"{state['last_answer']}\n\n(More details:\n{context[:500]}...)"
133
  elif feedback == "not helpful":
134
  adjusted_answer = qa_model(question=query + " Please provide more detailed information with examples.", context=context)['answer']
135
  else:
136
  state['chat_history'].append(("Bot", "Please provide valid feedback: good, too vague, not helpful."))
137
- log_message(f"Invalid feedback received: {feedback}")
138
- return state['chat_history'], state
139
  state['last_answer'] = adjusted_answer
140
  state['feedback_count'] += 1
141
  state['chat_history'].append(("Bot", f"Updated answer: {adjusted_answer}\nPlease provide feedback: good, too vague, not helpful."))
142
- log_message(f"Adjusted answer: {adjusted_answer}")
143
  elif state['mode'] == 'exited':
144
  state['chat_history'].append(("Bot", "Session is over. Please download the log."))
145
- log_message("User interacted after exiting.")
146
- return state['chat_history'], state
147
 
148
  # Initial state
149
  initial_state = {
@@ -154,20 +155,23 @@ initial_state = {
154
  'feedback_count': 0,
155
  'mode': 'waiting_for_upload',
156
  'chat_history': [("Bot", "Please upload a PDF or TXT file to start.")],
157
- 'last_answer': None,
158
- 'log_messages':# Initialize an empty list for log messages
159
  }
160
 
 
 
 
161
  # Logging function to store messages in memory
162
- def log_message(message):
163
  timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
164
  log_entry = f"{timestamp} - {message}"
165
- initial_state['log_messages'].append(log_entry)
 
166
 
167
  # Function to save logs to file
168
- def save_logs_to_file():
169
  with open("support_bot_log.txt", "w") as log_file:
170
- for log_message in initial_state['log_messages']:
171
  log_file.write(log_message + "\n")
172
 
173
  # Gradio interface
@@ -180,21 +184,21 @@ with gr.Blocks() as demo:
180
  log_file = gr.File(label="Download Log File") # Changed: No initial value
181
 
182
  # Process file upload
183
- file_upload.upload(process_file, inputs=[file_upload, state], outputs=[chat, state])
184
 
185
  # Handle user input and clear the textbox
186
- submit_btn.click(handle_input, inputs=[user_input, state], outputs=[chat, state]).then(lambda: "", None, user_input)
187
 
188
  # Update the log file just before download
189
- log_file.click(save_logs_to_file,, [log_file]) # Trigger save on click
190
 
191
  # Also save logs when user exits
192
  user_input.submit(
193
- lambda user_input, state: (
194
- save_logs_to_file() if user_input.lower() == "exit" else None,
195
  state
196
  ),
197
- [user_input, state],
198
  [log_file, state]
199
  )
200
 
 
 
1
  import gradio as gr
2
  from transformers import pipeline
3
  from sentence_transformers import SentenceTransformer, util
4
  import PyPDF2
5
+ import datetime
6
  import os
7
 
8
  # Load models
 
19
  return text
20
 
21
  # Find the most relevant section in the document
22
+ def find_relevant_section(query, sections, section_embeddings, log_messages):
23
  stopwords = {"and", "the", "is", "for", "to", "a", "an", "of", "in", "on", "at", "with", "by", "it", "as", "so", "what"}
24
 
25
  # Semantic search
 
31
 
32
  SIMILARITY_THRESHOLD = 0.4
33
  if similarity_score >= SIMILARITY_THRESHOLD:
34
+ log_messages = log_message(f"Found relevant section using embeddings for query: {query}", log_messages)
35
+ return best_section, log_messages
36
 
37
+ log_messages = log_message(f"Low similarity ({similarity_score}). Falling back to keyword search.", log_messages)
38
 
39
  # Keyword-based fallback search with stopword filtering
40
+ query_words = {word for word in query.lower().split() if word not in stopwords} # Corrected line
41
+ for section in sections:
42
  section_words = {word for word in section.lower().split() if word not in stopwords}
43
  common_words = query_words.intersection(section_words)
44
  if len(common_words) >= 2:
45
+ log_messages = log_message(f"Keyword match found for query: {query} with common words: {common_words}", log_messages)
46
+ return section, log_messages
47
 
48
+ log_messages = log_message(f"No good keyword match found. Returning default fallback response.", log_messages)
49
+ return "I don’t have enough information to answer that.", log_messages
50
 
51
  # Process the uploaded file with detailed logging
52
+ def process_file(file, state, log_messages):
53
  if file is None:
54
+ log_messages = log_message("No file uploaded.", log_messages)
55
+ return [("Bot", "Please upload a file.")], state, log_messages
56
 
57
  file_path = file.name
58
  if file_path.lower().endswith(".pdf"):
59
+ log_messages = log_message(f"Uploaded PDF file: {file_path}", log_messages)
60
  text = extract_text_from_pdf(file_path)
61
  elif file_path.lower().endswith(".txt"):
62
+ log_messages = log_message(f"Uploaded TXT file: {file_path}", log_messages)
63
  with open(file_path, 'r', encoding='utf-8') as f:
64
  text = f.read()
65
  else:
66
+ log_messages = log_message(f"Unsupported file format: {file_path}", log_messages)
67
+ return [("Bot", "Unsupported file format. Please upload a PDF or TXT file.")], state, log_messages
68
 
69
  sections = text.split('\n\n')
70
  section_embeddings = embedder.encode(sections, convert_to_tensor=True)
 
75
  state['feedback_count'] = 0
76
  state['mode'] = 'waiting_for_query'
77
  state['chat_history'] = [("Bot", "File processed. You can now ask questions.")]
78
+ log_messages = log_message(f"Processed file: {file_path}", log_messages)
79
+ return state['chat_history'], state, log_messages
80
 
81
  # Handle user input (queries and feedback)
82
+ def handle_input(user_input, state, log_messages):
83
  if state['mode'] == 'waiting_for_upload':
84
  state['chat_history'].append(("Bot", "Please upload a file first."))
85
+ log_messages = log_message("User attempted to interact without uploading a file.", log_messages)
86
+ return state['chat_history'], state, log_messages
87
  elif state['mode'] == 'waiting_for_query':
88
  if user_input.lower() == "exit":
89
+ log_messages = log_message("User entered 'exit'. Ending session.", log_messages)
90
  state['mode'] = 'exited'
91
  state['chat_history'].append(("User", "exit"))
92
  state['chat_history'].append(("Bot", "Session ended. You can download the log file."))
93
+ return state['chat_history'], state, log_messages
94
 
95
  query = user_input
96
  state['current_query'] = query
97
  state['feedback_count'] = 0
98
+ context, log_messages = find_relevant_section(query, state['sections'], state['section_embeddings'], log_messages)
99
  if context == "I don’t have enough information to answer that.":
100
  answer = context
101
  else:
 
106
  state['chat_history'].append(("User", query))
107
  state['chat_history'].append(("Bot", f"Answer: {answer}\nPlease provide feedback: good, too vague, not helpful."))
108
  # Log the query and initial answer here:
109
+ log_messages = log_message(f"Query: {query}, Answer: {answer}", log_messages)
110
  elif state['mode'] == 'waiting_for_feedback':
111
  if user_input.lower() == "exit":
112
+ log_messages = log_message("User entered 'exit'. Ending session.", log_messages)
113
  state['mode'] = 'exited'
114
  state['chat_history'].append(("User", "exit"))
115
  state['chat_history'].append(("Bot", "Session ended. You can download the log file."))
116
+ return state['chat_history'], state, log_messages
117
 
118
  feedback = user_input.lower()
119
  state['chat_history'].append(("User", feedback))
120
+ log_messages = log_message(f"Feedback: {feedback}", log_messages)
121
  if feedback == "good" or state['feedback_count'] >= 2:
122
  state['mode'] = 'waiting_for_query'
123
  if feedback == "good":
124
  state['chat_history'].append(("Bot", "Thank you for your feedback. You can ask another question."))
125
+ log_messages = log_message("Feedback accepted as 'good'. Waiting for next query.", log_messages)
126
  else:
127
  state['chat_history'].append(("Bot", "Maximum feedback iterations reached. You can ask another question."))
128
+ log_messages = log_message("Max feedback iterations reached. Waiting for next query.", log_messages)
129
  else:
130
  query = state['current_query']
131
+ context, log_messages = find_relevant_section(query, state['sections'], state['section_embeddings'], log_messages)
132
  if feedback == "too vague":
133
  adjusted_answer = f"{state['last_answer']}\n\n(More details:\n{context[:500]}...)"
134
  elif feedback == "not helpful":
135
  adjusted_answer = qa_model(question=query + " Please provide more detailed information with examples.", context=context)['answer']
136
  else:
137
  state['chat_history'].append(("Bot", "Please provide valid feedback: good, too vague, not helpful."))
138
+ log_messages = log_message(f"Invalid feedback received: {feedback}", log_messages)
139
+ return state['chat_history'], state, log_messages
140
  state['last_answer'] = adjusted_answer
141
  state['feedback_count'] += 1
142
  state['chat_history'].append(("Bot", f"Updated answer: {adjusted_answer}\nPlease provide feedback: good, too vague, not helpful."))
143
+ log_messages = log_message(f"Adjusted answer: {adjusted_answer}", log_messages)
144
  elif state['mode'] == 'exited':
145
  state['chat_history'].append(("Bot", "Session is over. Please download the log."))
146
+ log_messages = log_message("User interacted after exiting.", log_messages)
147
+ return state['chat_history'], state, log_messages
148
 
149
  # Initial state
150
  initial_state = {
 
155
  'feedback_count': 0,
156
  'mode': 'waiting_for_upload',
157
  'chat_history': [("Bot", "Please upload a PDF or TXT file to start.")],
158
+ 'last_answer': None
 
159
  }
160
 
161
+ # Initialize log_messages outside initial_state
162
+ log_messages =
163
+
164
  # Logging function to store messages in memory
165
+ def log_message(message, log_messages):
166
  timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
167
  log_entry = f"{timestamp} - {message}"
168
+ log_messages.append(log_entry)
169
+ return log_messages
170
 
171
  # Function to save logs to file
172
+ def save_logs_to_file(log_messages):
173
  with open("support_bot_log.txt", "w") as log_file:
174
+ for log_message in log_messages:
175
  log_file.write(log_message + "\n")
176
 
177
  # Gradio interface
 
184
  log_file = gr.File(label="Download Log File") # Changed: No initial value
185
 
186
  # Process file upload
187
+ file_upload.upload(process_file, inputs=[file_upload, state, gr.State(log_messages)], outputs=[chat, state, gr.State(log_messages)])
188
 
189
  # Handle user input and clear the textbox
190
+ submit_btn.click(handle_input, inputs=[user_input, state, gr.State(log_messages)], outputs=[chat, state, gr.State(log_messages)]).then(lambda: "", None, user_input)
191
 
192
  # Update the log file just before download
193
+ log_file.click(save_logs_to_file, inputs=[gr.State(log_messages)], outputs=[log_file]) # Trigger save on click
194
 
195
  # Also save logs when user exits
196
  user_input.submit(
197
+ lambda user_input, state, log_messages: (
198
+ save_logs_to_file(log_messages) if user_input.lower() == "exit" else None,
199
  state
200
  ),
201
+ [user_input, state, gr.State(log_messages)],
202
  [log_file, state]
203
  )
204