Mr-Geo commited on
Commit
e6f62c0
Β·
verified Β·
1 Parent(s): adec644

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -30
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import os
2
  import zipfile
 
3
  from dotenv import load_dotenv
4
  from groq import Groq
5
  import chromadb
@@ -9,6 +10,7 @@ from sentence_transformers import CrossEncoder
9
  import gradio as gr
10
  from datetime import datetime
11
  from huggingface_hub import hf_hub_download, HfApi
 
12
 
13
  # Load environment variables and initialize clients
14
  load_dotenv()
@@ -162,20 +164,55 @@ def get_context(message):
162
  print(f"\nFinal context length: {total_chars} characters")
163
  return context
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  def chat_response(message, history, model_name):
166
  """Chat response function for Gradio interface"""
167
  try:
168
- # Get context
169
  context = get_context(message)
170
-
171
- # Get current time and date
172
- current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
173
 
174
  # Build messages list
175
  messages = [{
176
  "role": "system",
177
  "content": f"""You are an AI assistant for the British Antarctic Survey (BAS). Your responses should be based ONLY on the context provided below.
178
-
179
  IMPORTANT INSTRUCTIONS:
180
  1. ALWAYS thoroughly check the provided context before saying you don't have information
181
  2. If you find ANY relevant information in the context, use it - even if it's not complete
@@ -183,18 +220,16 @@ IMPORTANT INSTRUCTIONS:
183
  4. When citing sources, put them on a new line after the relevant information like this:
184
  Here is some information about BAS.
185
  Source: https://www.bas.ac.uk/example
186
-
187
  5. Do not say things like:
188
  - "I don't have access to real-time information"
189
  - "I cannot browse the internet"
190
  Instead, share what IS in the context, and only say "I don't have enough information" if you truly find nothing relevant to the users question.
191
-
192
  6. Keep responses:
193
  - With emojis where appropriate
194
  - Without duplicate source citations
195
  - Based strictly on the context below
196
 
197
- Current Time: {current_time}
198
 
199
  Context: {context}"""
200
  }]
@@ -242,12 +277,11 @@ Context: {context}"""
242
  # Create collapsible thinking section
243
  if thinking_process:
244
  final_response = f"""<details>
245
- <summary>πŸ€” Click here to see the 'thinking' process</summary>
246
- <hr>
247
  <div style="font-size: 0.9em;">
248
- <i>πŸ’­{thinking_process}</i>
249
  </div>
250
- <hr>
251
  </details>
252
 
253
  {final_response}"""
@@ -259,49 +293,64 @@ Context: {context}"""
259
  else:
260
  final_response += content
261
  yield final_response
262
-
 
 
263
  print("\n=== LLM Response End ===\n")
264
 
265
  except Exception as e:
266
  error_msg = f"An error occurred: {str(e)}"
267
  print(f"\nERROR: {error_msg}")
 
 
 
268
  yield error_msg
269
-
270
  if __name__ == "__main__":
271
  try:
272
  print("\n=== Starting Application ===")
273
 
274
- # Initialise system
 
 
 
275
  print("Initialising ChromaDB...")
276
  chroma_client, collection, reranker = initialize_system()
277
  print(f"Found {collection.count()} documents in collection")
278
 
279
  print("\nCreating Gradio interface...")
280
 
281
- # Create a simple Gradio interface
282
  demo = gr.Blocks()
283
 
284
  with demo:
285
- gr.Markdown("# British Antarctic Survey Website Chat Assistant 🌍")
286
- gr.Markdown("Ask questions about the BAS website. This system accesses text data from 11,982 unique BAS URLs (6GB vector database) πŸ“š")
287
- # Add model selector
288
  model_selector = gr.Dropdown(
289
  choices=[
290
- "llama-3.3-70b-versatile",
291
  "llama-3.1-8b-instant",
 
 
292
  "mixtral-8x7b-32768",
293
  "deepseek-r1-distill-llama-70b"
294
  ],
295
- value="llama-3.3-70b-versatile",
296
- label="Select AI Model πŸ€–",
297
- info="Choose which AI model to use for responses - select 'deepseek-r1-distill-llama-70b' for the 'thinking' AI search"
298
  )
299
 
300
- chatbot = gr.Chatbot(height=600)
301
- msg = gr.Textbox(placeholder="Ask a question or select an example question... πŸ€”", label="Your question")
302
- clear = gr.Button("Clear 🧹")
 
 
 
 
 
 
 
 
303
 
304
- # Add example questions
305
  gr.Examples(
306
  examples=[
307
  "What research stations does BAS operate in Antarctica? πŸ”οΈ",
@@ -324,11 +373,13 @@ if __name__ == "__main__":
324
  msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
325
  bot, [chatbot, model_selector], chatbot
326
  )
 
 
 
327
 
328
  clear.click(lambda: None, None, chatbot, queue=False)
329
-
330
- # Launch with minimal configuration
331
- demo.queue()
332
  demo.launch(
333
  server_name="0.0.0.0",
334
  server_port=7860,
 
1
  import os
2
  import zipfile
3
+ import json
4
  from dotenv import load_dotenv
5
  from groq import Groq
6
  import chromadb
 
10
  import gradio as gr
11
  from datetime import datetime
12
  from huggingface_hub import hf_hub_download, HfApi
13
+ from pathlib import Path
14
 
15
  # Load environment variables and initialize clients
16
  load_dotenv()
 
164
  print(f"\nFinal context length: {total_chars} characters")
165
  return context
166
 
167
+ def log_conversation(timestamp, user_message, assistant_response, model_name, context, error=None):
168
+ """Log conversation details to a JSON file"""
169
+ log_dir = Path("logs")
170
+ log_dir.mkdir(exist_ok=True)
171
+
172
+ # Create a log entry
173
+ log_entry = {
174
+ "timestamp": timestamp,
175
+ "model_name": model_name,
176
+ "user_message": user_message,
177
+ "assistant_response": assistant_response,
178
+ "context": context,
179
+ "error": str(error) if error else None
180
+ }
181
+
182
+ # Use the current date for the log file name
183
+ current_date = datetime.now().strftime("%Y-%m-%d")
184
+ log_file = log_dir / f"conversation_log_{current_date}.json"
185
+
186
+ try:
187
+ # Load existing logs if file exists
188
+ if log_file.exists():
189
+ with open(log_file, 'r', encoding='utf-8') as f:
190
+ logs = json.load(f)
191
+ else:
192
+ logs = []
193
+
194
+ # Append new log entry
195
+ logs.append(log_entry)
196
+
197
+ # Write updated logs
198
+ with open(log_file, 'w', encoding='utf-8') as f:
199
+ json.dump(logs, f, ensure_ascii=False, indent=2)
200
+
201
+ print(f"\n✍️ Logged conversation to {log_file}")
202
+ except Exception as e:
203
+ print(f"\n⚠️ Error logging conversation: {str(e)}")
204
+
205
  def chat_response(message, history, model_name):
206
  """Chat response function for Gradio interface"""
207
  try:
208
+ # Get context and timestamp
209
  context = get_context(message)
210
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 
 
211
 
212
  # Build messages list
213
  messages = [{
214
  "role": "system",
215
  "content": f"""You are an AI assistant for the British Antarctic Survey (BAS). Your responses should be based ONLY on the context provided below.
 
216
  IMPORTANT INSTRUCTIONS:
217
  1. ALWAYS thoroughly check the provided context before saying you don't have information
218
  2. If you find ANY relevant information in the context, use it - even if it's not complete
 
220
  4. When citing sources, put them on a new line after the relevant information like this:
221
  Here is some information about BAS.
222
  Source: https://www.bas.ac.uk/example
 
223
  5. Do not say things like:
224
  - "I don't have access to real-time information"
225
  - "I cannot browse the internet"
226
  Instead, share what IS in the context, and only say "I don't have enough information" if you truly find nothing relevant to the users question.
 
227
  6. Keep responses:
228
  - With emojis where appropriate
229
  - Without duplicate source citations
230
  - Based strictly on the context below
231
 
232
+ Current Time: {timestamp}
233
 
234
  Context: {context}"""
235
  }]
 
277
  # Create collapsible thinking section
278
  if thinking_process:
279
  final_response = f"""<details>
280
+ <summary>πŸ€” <u>Click to see 'thinking' process</u></summary>
 
281
  <div style="font-size: 0.9em;">
282
+ <i>πŸ’­{thinking_process}πŸ’­</i>
283
  </div>
284
+ <hr style="margin: 0; height: 2px;">
285
  </details>
286
 
287
  {final_response}"""
 
293
  else:
294
  final_response += content
295
  yield final_response
296
+
297
+
298
+ log_conversation(timestamp, message, final_response, model_name, context)
299
  print("\n=== LLM Response End ===\n")
300
 
301
  except Exception as e:
302
  error_msg = f"An error occurred: {str(e)}"
303
  print(f"\nERROR: {error_msg}")
304
+
305
+ log_conversation(datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
306
+ message, error_msg, model_name, context, error=e)
307
  yield error_msg
308
+
309
  if __name__ == "__main__":
310
  try:
311
  print("\n=== Starting Application ===")
312
 
313
+
314
+ Path("logs").mkdir(exist_ok=True)
315
+
316
+
317
  print("Initialising ChromaDB...")
318
  chroma_client, collection, reranker = initialize_system()
319
  print(f"Found {collection.count()} documents in collection")
320
 
321
  print("\nCreating Gradio interface...")
322
 
323
+
324
  demo = gr.Blocks()
325
 
326
  with demo:
327
+ gr.Markdown("# πŸŒβ„οΈBritish Antarctic Survey Website Chat Assistant πŸ§ŠπŸ€–")
328
+ gr.Markdown("Accesses text data from 11,982 unique BAS URLs (6GB [Vector Database](https://huggingface.co/datasets/Mr-Geo/chroma_db/tree/main/) πŸ“š extracted 02/02/2025) | Created with open source technologies: [Gradio](https://gradio.app) for the interface 🎨, [Groq](https://groq.com) API for rapid LLM processing ⚑, and [Chroma](https://www.trychroma.com/) as the vector database πŸ’»πŸ”")
 
329
  model_selector = gr.Dropdown(
330
  choices=[
 
331
  "llama-3.1-8b-instant",
332
+ "llama-3.3-70b-versatile",
333
+ "llama-3.3-70b-specdec",
334
  "mixtral-8x7b-32768",
335
  "deepseek-r1-distill-llama-70b"
336
  ],
337
+ value="llama-3.1-8b-instant",
338
+ label="Select AI Large Language Model πŸ€–",
339
+ info="Choose which AI model to use for responses - Select 'deepseek' for the 'thinking' AI search πŸ’­"
340
  )
341
 
342
+ chatbot = gr.Chatbot(height=550)
343
+ with gr.Row(equal_height=True):
344
+ msg = gr.Textbox(
345
+ placeholder="What would you like to know? Or choose an example question...❓",
346
+ label="Your question",
347
+ show_label=True,
348
+ container=True,
349
+ scale=20
350
+ )
351
+ send = gr.Button("Send ⬆️", scale=1, min_width=50)
352
+ clear = gr.Button("Clear chat history 🧹")
353
 
 
354
  gr.Examples(
355
  examples=[
356
  "What research stations does BAS operate in Antarctica? πŸ”οΈ",
 
373
  msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
374
  bot, [chatbot, model_selector], chatbot
375
  )
376
+ send.click(user, [msg, chatbot], [msg, chatbot], queue=False).then(
377
+ bot, [chatbot, model_selector], chatbot
378
+ )
379
 
380
  clear.click(lambda: None, None, chatbot, queue=False)
381
+
382
+ gr.Markdown("<footer style='text-align: center; margin-top: 5px;'>πŸ€– AI-generated content; while the Chat Assistant strives for accuracy, errors may occur; please thoroughly check critical information πŸ€–<br>⚠️ <strong><u>Disclaimer: This system was not produced by the British Antarctic Survey (BAS) and AI generated output does not reflect the views or opinions of BAS</u></strong> ⚠️ <br>(just a bit of fun :D)</footer>")
 
383
  demo.launch(
384
  server_name="0.0.0.0",
385
  server_port=7860,