Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -9,8 +9,9 @@ import torch
|
|
9 |
from sentence_transformers import CrossEncoder
|
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()
|
@@ -165,10 +166,7 @@ def get_context(message):
|
|
165 |
return context
|
166 |
|
167 |
def log_conversation(timestamp, user_message, assistant_response, model_name, context, error=None):
|
168 |
-
"""Log conversation details to
|
169 |
-
log_dir = Path("logs")
|
170 |
-
log_dir.mkdir(exist_ok=True)
|
171 |
-
|
172 |
# Create a log entry
|
173 |
log_entry = {
|
174 |
"timestamp": timestamp,
|
@@ -179,28 +177,82 @@ def log_conversation(timestamp, user_message, assistant_response, model_name, co
|
|
179 |
"error": str(error) if error else None
|
180 |
}
|
181 |
|
182 |
-
#
|
|
|
183 |
current_date = datetime.now().strftime("%Y-%m-%d")
|
184 |
-
log_file = log_dir / f"conversation_log_{current_date}.json"
|
185 |
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
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 |
-
|
202 |
-
|
203 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
|
205 |
def chat_response(message, history, model_name):
|
206 |
"""Chat response function for Gradio interface"""
|
@@ -241,7 +293,7 @@ Context: {context}"""
|
|
241 |
# Add history and current message
|
242 |
if history:
|
243 |
for h in history:
|
244 |
-
messages.append({"role": "user", "content": str(h[0])})
|
245 |
if h[1]: # If there's a response
|
246 |
messages.append({"role": "assistant", "content": str(h[1])})
|
247 |
|
@@ -279,7 +331,7 @@ Context: {context}"""
|
|
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}
|
283 |
</div>
|
284 |
<hr style="margin: 0; height: 2px;">
|
285 |
</details>
|
@@ -294,14 +346,12 @@ Context: {context}"""
|
|
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
|
@@ -325,7 +375,7 @@ if __name__ == "__main__":
|
|
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)
|
329 |
model_selector = gr.Dropdown(
|
330 |
choices=[
|
331 |
"llama-3.1-8b-instant",
|
@@ -336,7 +386,7 @@ if __name__ == "__main__":
|
|
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
|
340 |
)
|
341 |
|
342 |
chatbot = gr.Chatbot(height=600)
|
|
|
9 |
from sentence_transformers import CrossEncoder
|
10 |
import gradio as gr
|
11 |
from datetime import datetime
|
12 |
+
from huggingface_hub import hf_hub_download, HfApi, CommitOperationAdd
|
13 |
from pathlib import Path
|
14 |
+
import tempfile
|
15 |
|
16 |
# Load environment variables and initialize clients
|
17 |
load_dotenv()
|
|
|
166 |
return context
|
167 |
|
168 |
def log_conversation(timestamp, user_message, assistant_response, model_name, context, error=None):
|
169 |
+
"""Log conversation details to JSON file - local directory or HuggingFace Dataset repository"""
|
|
|
|
|
|
|
170 |
# Create a log entry
|
171 |
log_entry = {
|
172 |
"timestamp": timestamp,
|
|
|
177 |
"error": str(error) if error else None
|
178 |
}
|
179 |
|
180 |
+
# Check if running on Hugging Face Spaces
|
181 |
+
is_hf_space = os.getenv('SPACE_ID') is not None
|
182 |
current_date = datetime.now().strftime("%Y-%m-%d")
|
|
|
183 |
|
184 |
+
if is_hf_space:
|
185 |
+
try:
|
186 |
+
# Initialize Hugging Face API
|
187 |
+
api = HfApi(token=hf_token)
|
188 |
+
filename = f"conversation_logs/daily_{current_date}.json"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
|
190 |
+
try:
|
191 |
+
# Try to download existing file
|
192 |
+
existing_file = api.hf_hub_download(
|
193 |
+
repo_id="Mr-Geo/bas_chat_logs",
|
194 |
+
filename=filename,
|
195 |
+
repo_type="dataset",
|
196 |
+
token=hf_token
|
197 |
+
)
|
198 |
+
# Load existing logs
|
199 |
+
with open(existing_file, 'r', encoding='utf-8') as f:
|
200 |
+
logs = json.load(f)
|
201 |
+
except Exception:
|
202 |
+
# File doesn't exist yet, start with empty list
|
203 |
+
logs = []
|
204 |
+
|
205 |
+
# Append new log entry
|
206 |
+
logs.append(log_entry)
|
207 |
+
|
208 |
+
# Create temporary file with updated logs
|
209 |
+
with tempfile.NamedTemporaryFile(mode='w', encoding='utf-8', delete=False, suffix='.json') as temp_file:
|
210 |
+
json.dump(logs, temp_file, ensure_ascii=False, indent=2)
|
211 |
+
temp_file_path = temp_file.name
|
212 |
+
|
213 |
+
# Push to the dataset repository
|
214 |
+
api.create_commit(
|
215 |
+
repo_id="Mr-Geo/bas_chat_logs",
|
216 |
+
repo_type="dataset",
|
217 |
+
operations=[
|
218 |
+
CommitOperationAdd(
|
219 |
+
path_in_repo=filename,
|
220 |
+
path_or_fileobj=temp_file_path,
|
221 |
+
commit_message=f"Update conversation logs for {current_date}"
|
222 |
+
)
|
223 |
+
],
|
224 |
+
commit_message=f"Update conversation logs for {current_date}"
|
225 |
+
)
|
226 |
+
|
227 |
+
# Clean up temporary file
|
228 |
+
os.unlink(temp_file_path)
|
229 |
+
|
230 |
+
except Exception as e:
|
231 |
+
print(f"\nβ οΈ Error logging conversation to HuggingFace: {str(e)}")
|
232 |
+
else:
|
233 |
+
# Local environment - save to file
|
234 |
+
try:
|
235 |
+
log_dir = Path("logs")
|
236 |
+
log_dir.mkdir(exist_ok=True)
|
237 |
+
|
238 |
+
log_file = log_dir / f"conversation_log_{current_date}.json"
|
239 |
+
|
240 |
+
# Load existing logs if file exists
|
241 |
+
if log_file.exists():
|
242 |
+
with open(log_file, 'r', encoding='utf-8') as f:
|
243 |
+
logs = json.load(f)
|
244 |
+
else:
|
245 |
+
logs = []
|
246 |
+
|
247 |
+
# Append new log entry
|
248 |
+
logs.append(log_entry)
|
249 |
+
|
250 |
+
# Write updated logs
|
251 |
+
with open(log_file, 'w', encoding='utf-8') as f:
|
252 |
+
json.dump(logs, f, ensure_ascii=False, indent=2)
|
253 |
+
|
254 |
+
except Exception as e:
|
255 |
+
print(f"\nβ οΈ Error logging conversation locally: {str(e)}")
|
256 |
|
257 |
def chat_response(message, history, model_name):
|
258 |
"""Chat response function for Gradio interface"""
|
|
|
293 |
# Add history and current message
|
294 |
if history:
|
295 |
for h in history:
|
296 |
+
messages.append({"role": "user", "content": f"{str(h[0])} at BAS"})
|
297 |
if h[1]: # If there's a response
|
298 |
messages.append({"role": "assistant", "content": str(h[1])})
|
299 |
|
|
|
331 |
final_response = f"""<details>
|
332 |
<summary>π€ <u>Click to see 'thinking' process</u></summary>
|
333 |
<div style="font-size: 0.9em;">
|
334 |
+
<i>π{thinking_process}</i>
|
335 |
</div>
|
336 |
<hr style="margin: 0; height: 2px;">
|
337 |
</details>
|
|
|
346 |
final_response += content
|
347 |
yield final_response
|
348 |
|
|
|
349 |
log_conversation(timestamp, message, final_response, model_name, context)
|
350 |
print("\n=== LLM Response End ===\n")
|
351 |
|
352 |
except Exception as e:
|
353 |
error_msg = f"An error occurred: {str(e)}"
|
354 |
print(f"\nERROR: {error_msg}")
|
|
|
355 |
log_conversation(datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
356 |
message, error_msg, model_name, context, error=e)
|
357 |
yield error_msg
|
|
|
375 |
|
376 |
with demo:
|
377 |
gr.Markdown("# πβοΈBritish Antarctic Survey Website Chat Assistant π§π€")
|
378 |
+
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) for LLM processing β‘, and [Chroma](https://www.trychroma.com/) as the vector database π»")
|
379 |
model_selector = gr.Dropdown(
|
380 |
choices=[
|
381 |
"llama-3.1-8b-instant",
|
|
|
386 |
],
|
387 |
value="llama-3.1-8b-instant",
|
388 |
label="Select AI Large Language Model π€",
|
389 |
+
info="Choose which AI model to use for responses (all models running on [GroqCloud](https://groq.com/groqrack/)"
|
390 |
)
|
391 |
|
392 |
chatbot = gr.Chatbot(height=600)
|