Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -45,7 +45,7 @@ import pytesseract
|
|
| 45 |
from PIL import Image
|
| 46 |
|
| 47 |
# Import Juno AI Prompts System
|
| 48 |
-
from prompts import juno_prompts, get_main_conversation_prompt, get_document_summary_prompt, get_rag_prompt, get_streaming_prompt, get_fallback_responses
|
| 49 |
|
| 50 |
# Load environment variables
|
| 51 |
load_dotenv()
|
|
@@ -101,41 +101,49 @@ class ChatbotWithMemoryAndRAG:
|
|
| 101 |
self.vectorstore = None
|
| 102 |
self.chat_history = []
|
| 103 |
self.memory = {}
|
| 104 |
-
# NEWLY ADDED:
|
| 105 |
-
self.
|
|
|
|
| 106 |
self.session_id = str(uuid.uuid4())
|
| 107 |
self.last_rate_limit = None
|
| 108 |
self.consecutive_rate_limits = 0
|
| 109 |
self.prompts = juno_prompts
|
| 110 |
-
# NEWLY ADDED: Initialize user info storage
|
| 111 |
-
self._initialize_user_storage()
|
| 112 |
logging.info(f"🤖 Juno AI initialized with session ID: {self.session_id}")
|
| 113 |
|
| 114 |
-
def
|
| 115 |
-
"""
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
"
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
"
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
|
| 140 |
def _retry_with_backoff(self, func, max_retries=5, base_delay=2):
|
| 141 |
"""Improved retry function with progressive backoff for rate limit handling"""
|
|
@@ -182,108 +190,18 @@ class ChatbotWithMemoryAndRAG:
|
|
| 182 |
logging.warning(f"Generating fallback response for message: '{user_message[:50]}...'")
|
| 183 |
fallback_templates = get_fallback_responses()
|
| 184 |
template = random.choice(fallback_templates)
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
if user_name:
|
| 188 |
-
response =
|
|
|
|
|
|
|
| 189 |
else:
|
| 190 |
response = template.format(user_message_preview=user_message[:50])
|
|
|
|
| 191 |
self.chat_history.append({"user": user_message, "bot": response, "timestamp": datetime.now().isoformat(), "fallback": True})
|
| 192 |
return response
|
| 193 |
|
| 194 |
-
def _get_user_name(self):
|
| 195 |
-
"""Get the user's preferred name from stored information"""
|
| 196 |
-
if self.user_info.get("name"):
|
| 197 |
-
name_info = self.user_info["name"]
|
| 198 |
-
return (name_info.get("nickname") or
|
| 199 |
-
name_info.get("first_name") or
|
| 200 |
-
name_info.get("full_name") or
|
| 201 |
-
None)
|
| 202 |
-
return None
|
| 203 |
-
|
| 204 |
-
def _extract_user_information(self, user_message, bot_response):
|
| 205 |
-
"""Extract user information from conversation using AI"""
|
| 206 |
-
def _extract():
|
| 207 |
-
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 208 |
-
prompt = get_user_extraction_prompt(user_message, bot_response)
|
| 209 |
-
return model.generate_content(prompt).text
|
| 210 |
-
|
| 211 |
-
try:
|
| 212 |
-
extraction_result = self._retry_with_backoff(_extract, max_retries=3, base_delay=1)
|
| 213 |
-
# Parse JSON response
|
| 214 |
-
try:
|
| 215 |
-
new_user_info = json.loads(extraction_result)
|
| 216 |
-
if new_user_info and any(new_user_info.values()):
|
| 217 |
-
self._consolidate_user_information(new_user_info)
|
| 218 |
-
except json.JSONDecodeError:
|
| 219 |
-
logging.warning(f"Failed to parse user information extraction: {extraction_result}")
|
| 220 |
-
except Exception as e:
|
| 221 |
-
logging.error(f"Error extracting user information: {e}")
|
| 222 |
-
|
| 223 |
-
def _consolidate_user_information(self, new_user_info):
|
| 224 |
-
"""Consolidate new user information with existing information"""
|
| 225 |
-
def _consolidate():
|
| 226 |
-
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 227 |
-
prompt = get_memory_consolidation_prompt(self.user_info, new_user_info)
|
| 228 |
-
return model.generate_content(prompt).text
|
| 229 |
-
|
| 230 |
-
try:
|
| 231 |
-
consolidation_result = self._retry_with_backoff(_consolidate, max_retries=3, base_delay=1)
|
| 232 |
-
# Parse JSON response and update user_info
|
| 233 |
-
try:
|
| 234 |
-
consolidated_info = json.loads(consolidation_result)
|
| 235 |
-
self.user_info = consolidated_info
|
| 236 |
-
logging.info("User information updated successfully.")
|
| 237 |
-
except json.JSONDecodeError:
|
| 238 |
-
# Manual consolidation as fallback
|
| 239 |
-
self._manual_consolidation(new_user_info)
|
| 240 |
-
except Exception as e:
|
| 241 |
-
logging.error(f"Error consolidating user information: {e}")
|
| 242 |
-
# Fallback to manual consolidation
|
| 243 |
-
self._manual_consolidation(new_user_info)
|
| 244 |
-
|
| 245 |
-
def _manual_consolidation(self, new_user_info):
|
| 246 |
-
"""Manual consolidation as fallback when AI consolidation fails"""
|
| 247 |
-
try:
|
| 248 |
-
# Merge name information
|
| 249 |
-
if new_user_info.get("name"):
|
| 250 |
-
for key, value in new_user_info["name"].items():
|
| 251 |
-
if value and value != "null":
|
| 252 |
-
self.user_info["name"][key] = value
|
| 253 |
-
|
| 254 |
-
# Merge personal details
|
| 255 |
-
if new_user_info.get("personal_details"):
|
| 256 |
-
for key, value in new_user_info["personal_details"].items():
|
| 257 |
-
if value and value != "null":
|
| 258 |
-
self.user_info["personal_details"][key] = value
|
| 259 |
-
|
| 260 |
-
# Merge preferences (lists)
|
| 261 |
-
if new_user_info.get("preferences"):
|
| 262 |
-
for key, values in new_user_info["preferences"].items():
|
| 263 |
-
if values:
|
| 264 |
-
existing_list = self.user_info["preferences"].get(key, [])
|
| 265 |
-
for item in values:
|
| 266 |
-
if item not in existing_list:
|
| 267 |
-
existing_list.append(item)
|
| 268 |
-
self.user_info["preferences"][key] = existing_list
|
| 269 |
-
|
| 270 |
-
# Merge goals and context (lists)
|
| 271 |
-
for key in ["goals", "context"]:
|
| 272 |
-
if new_user_info.get(key):
|
| 273 |
-
existing_list = self.user_info.get(key, [])
|
| 274 |
-
for item in new_user_info[key]:
|
| 275 |
-
if item not in existing_list:
|
| 276 |
-
existing_list.append(item)
|
| 277 |
-
self.user_info[key] = existing_list
|
| 278 |
-
|
| 279 |
-
# Update communication preferences
|
| 280 |
-
if new_user_info.get("communication_preferences"):
|
| 281 |
-
self.user_info["communication_preferences"] = new_user_info["communication_preferences"]
|
| 282 |
-
|
| 283 |
-
logging.info("User information manually consolidated.")
|
| 284 |
-
except Exception as e:
|
| 285 |
-
logging.error(f"Error in manual consolidation: {e}")
|
| 286 |
-
|
| 287 |
def extract_text_from_pdf(self, pdf_content):
|
| 288 |
"""Extract text content from PDF bytes with OCR fallback"""
|
| 289 |
try:
|
|
@@ -358,6 +276,17 @@ class ChatbotWithMemoryAndRAG:
|
|
| 358 |
|
| 359 |
def generate_response(self, user_message, context=""):
|
| 360 |
"""Generate response using Juno AI prompts"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
def _generate():
|
| 362 |
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 363 |
conversation_history = []
|
|
@@ -365,22 +294,22 @@ class ChatbotWithMemoryAndRAG:
|
|
| 365 |
for exchange in self.chat_history[-3:]:
|
| 366 |
if not exchange.get('fallback', False):
|
| 367 |
conversation_history.append({'user': exchange['user'], 'bot': exchange['bot'], 'timestamp': exchange.get('timestamp', '')})
|
| 368 |
-
|
| 369 |
-
prompt
|
| 370 |
-
|
| 371 |
-
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
return model.generate_content(prompt).text
|
| 377 |
|
| 378 |
try:
|
| 379 |
bot_response = self._retry_with_backoff(_generate)
|
| 380 |
self.chat_history.append({"user": user_message, "bot": bot_response, "timestamp": datetime.now().isoformat()})
|
| 381 |
self.update_memory(user_message, bot_response)
|
| 382 |
-
# NEWLY ADDED: Extract
|
| 383 |
-
self.
|
| 384 |
return bot_response
|
| 385 |
except (ResourceExhausted, GoogleAPIError):
|
| 386 |
return self._fallback_response(user_message)
|
|
@@ -432,22 +361,30 @@ class ChatbotWithMemoryAndRAG:
|
|
| 432 |
|
| 433 |
def generate_rag_response(self, user_query, context, sources=None):
|
| 434 |
"""Generate RAG response using Juno AI prompts"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
def _generate_rag():
|
| 436 |
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 437 |
context_chunks = [context[i:i+2000] for i in range(0, len(context), 2000)]
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
)
|
|
|
|
| 445 |
return model.generate_content(prompt).text
|
| 446 |
|
| 447 |
try:
|
| 448 |
response = self._retry_with_backoff(_generate_rag)
|
| 449 |
-
# NEWLY ADDED: Extract
|
| 450 |
-
self.
|
| 451 |
return response
|
| 452 |
except (ResourceExhausted, GoogleAPIError):
|
| 453 |
return self._fallback_response(user_query)
|
|
@@ -497,14 +434,23 @@ class ChatbotWithMemoryAndRAG:
|
|
| 497 |
|
| 498 |
def generate_streaming_response(self, user_message, context=""):
|
| 499 |
"""Generate streaming response using Juno AI prompts"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
def _generate_stream():
|
| 501 |
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
|
|
|
|
|
|
|
| 508 |
return model.generate_content(prompt, stream=True)
|
| 509 |
|
| 510 |
try:
|
|
@@ -608,7 +554,8 @@ def summarize_document():
|
|
| 608 |
def get_memory():
|
| 609 |
return jsonify({
|
| 610 |
'memory': chatbot.memory,
|
| 611 |
-
'
|
|
|
|
| 612 |
'chat_history_length': len(chatbot.chat_history),
|
| 613 |
'has_vectorstore': chatbot.vectorstore is not None,
|
| 614 |
'session_id': chatbot.session_id
|
|
@@ -695,8 +642,8 @@ def chat_stream():
|
|
| 695 |
|
| 696 |
chatbot.chat_history.append({"user": user_message, "bot": full_response, "timestamp": datetime.now().isoformat()})
|
| 697 |
chatbot.update_memory(user_message, full_response)
|
| 698 |
-
# NEWLY ADDED: Extract
|
| 699 |
-
chatbot.
|
| 700 |
|
| 701 |
return jsonify({
|
| 702 |
'response': full_response,
|
|
@@ -798,53 +745,10 @@ def edit_message(message_index):
|
|
| 798 |
logging.error(f"Error in /api/messages/{message_index}/edit: {e}", exc_info=True)
|
| 799 |
return jsonify({'error': 'An internal server error occurred.'}), 500
|
| 800 |
|
| 801 |
-
# NEWLY ADDED: User information management endpoints
|
| 802 |
-
|
| 803 |
-
@app.route('/api/user-info', methods=['GET'])
|
| 804 |
-
def get_user_info():
|
| 805 |
-
"""Get stored user information"""
|
| 806 |
-
try:
|
| 807 |
-
return jsonify({
|
| 808 |
-
'user_info': chatbot.user_info,
|
| 809 |
-
'has_user_info': any(v for v in chatbot.user_info.values() if v),
|
| 810 |
-
'user_name': chatbot._get_user_name()
|
| 811 |
-
})
|
| 812 |
-
except Exception as e:
|
| 813 |
-
logging.error(f"Error in /api/user-info GET: {e}", exc_info=True)
|
| 814 |
-
return jsonify({'error': 'An internal server error occurred.'}), 500
|
| 815 |
-
|
| 816 |
-
@app.route('/api/user-info', methods=['PUT'])
|
| 817 |
-
def update_user_info():
|
| 818 |
-
"""Update user information manually"""
|
| 819 |
-
try:
|
| 820 |
-
data = request.json
|
| 821 |
-
new_info = data.get('user_info', {})
|
| 822 |
-
if new_info:
|
| 823 |
-
chatbot._consolidate_user_information(new_info)
|
| 824 |
-
return jsonify({
|
| 825 |
-
'message': 'User information updated successfully',
|
| 826 |
-
'user_info': chatbot.user_info
|
| 827 |
-
})
|
| 828 |
-
else:
|
| 829 |
-
return jsonify({'error': 'No user information provided'}), 400
|
| 830 |
-
except Exception as e:
|
| 831 |
-
logging.error(f"Error in /api/user-info PUT: {e}", exc_info=True)
|
| 832 |
-
return jsonify({'error': 'An internal server error occurred.'}), 500
|
| 833 |
-
|
| 834 |
-
@app.route('/api/user-info', methods=['DELETE'])
|
| 835 |
-
def clear_user_info():
|
| 836 |
-
"""Clear all stored user information"""
|
| 837 |
-
try:
|
| 838 |
-
chatbot._initialize_user_storage()
|
| 839 |
-
return jsonify({'message': 'User information cleared successfully'})
|
| 840 |
-
except Exception as e:
|
| 841 |
-
logging.error(f"Error in /api/user-info DELETE: {e}", exc_info=True)
|
| 842 |
-
return jsonify({'error': 'An internal server error occurred.'}), 500
|
| 843 |
-
|
| 844 |
if __name__ == '__main__':
|
| 845 |
logging.info("🚀 Starting Juno AI Server...")
|
| 846 |
logging.info("🤖 Advanced AI Assistant with Document Processing, Web Scraping, and Memory")
|
| 847 |
logging.info("🌟 Powered by Juno AI Prompts System")
|
| 848 |
-
logging.info("🧠 Enhanced with User
|
| 849 |
port = int(os.environ.get("PORT", 7860))
|
| 850 |
app.run(debug=False, host='0.0.0.0', port=port)
|
|
|
|
| 45 |
from PIL import Image
|
| 46 |
|
| 47 |
# Import Juno AI Prompts System
|
| 48 |
+
from prompts import juno_prompts, get_main_conversation_prompt, get_document_summary_prompt, get_rag_prompt, get_streaming_prompt, get_fallback_responses
|
| 49 |
|
| 50 |
# Load environment variables
|
| 51 |
load_dotenv()
|
|
|
|
| 101 |
self.vectorstore = None
|
| 102 |
self.chat_history = []
|
| 103 |
self.memory = {}
|
| 104 |
+
# NEWLY ADDED: Simple user information storage
|
| 105 |
+
self.user_name = None
|
| 106 |
+
self.user_details = {}
|
| 107 |
self.session_id = str(uuid.uuid4())
|
| 108 |
self.last_rate_limit = None
|
| 109 |
self.consecutive_rate_limits = 0
|
| 110 |
self.prompts = juno_prompts
|
|
|
|
|
|
|
| 111 |
logging.info(f"🤖 Juno AI initialized with session ID: {self.session_id}")
|
| 112 |
|
| 113 |
+
def _extract_name_from_message(self, user_message, bot_response):
|
| 114 |
+
"""Simple name extraction from user messages"""
|
| 115 |
+
message_lower = user_message.lower()
|
| 116 |
+
|
| 117 |
+
# Pattern 1: "i am [name]" or "I'm [name]"
|
| 118 |
+
patterns = [
|
| 119 |
+
r"i am ([a-zA-Z]+)",
|
| 120 |
+
r"i'm ([a-zA-Z]+)",
|
| 121 |
+
r"my name is ([a-zA-Z]+)",
|
| 122 |
+
r"call me ([a-zA-Z]+)",
|
| 123 |
+
r"name's ([a-zA-Z]+)"
|
| 124 |
+
]
|
| 125 |
+
|
| 126 |
+
for pattern in patterns:
|
| 127 |
+
match = re.search(pattern, message_lower)
|
| 128 |
+
if match:
|
| 129 |
+
name = match.group(1).capitalize()
|
| 130 |
+
self.user_name = name
|
| 131 |
+
self.user_details["name"] = name
|
| 132 |
+
logging.info(f"Extracted user name: {name}")
|
| 133 |
+
return name
|
| 134 |
+
return None
|
| 135 |
+
|
| 136 |
+
def _check_for_name_query(self, user_message):
|
| 137 |
+
"""Check if user is asking about their name"""
|
| 138 |
+
message_lower = user_message.lower()
|
| 139 |
+
name_queries = [
|
| 140 |
+
"what is my name",
|
| 141 |
+
"what's my name",
|
| 142 |
+
"do you know my name",
|
| 143 |
+
"remember my name",
|
| 144 |
+
"my name"
|
| 145 |
+
]
|
| 146 |
+
return any(query in message_lower for query in name_queries)
|
| 147 |
|
| 148 |
def _retry_with_backoff(self, func, max_retries=5, base_delay=2):
|
| 149 |
"""Improved retry function with progressive backoff for rate limit handling"""
|
|
|
|
| 190 |
logging.warning(f"Generating fallback response for message: '{user_message[:50]}...'")
|
| 191 |
fallback_templates = get_fallback_responses()
|
| 192 |
template = random.choice(fallback_templates)
|
| 193 |
+
|
| 194 |
+
# NEWLY ADDED: Include user name in fallback if available
|
| 195 |
+
if self.user_name and self._check_for_name_query(user_message):
|
| 196 |
+
response = f"Your name is {self.user_name}! I remember when you told me."
|
| 197 |
+
elif self.user_name:
|
| 198 |
+
response = template.format(user_message_preview=user_message[:50]).replace("Your", f"{self.user_name}'s")
|
| 199 |
else:
|
| 200 |
response = template.format(user_message_preview=user_message[:50])
|
| 201 |
+
|
| 202 |
self.chat_history.append({"user": user_message, "bot": response, "timestamp": datetime.now().isoformat(), "fallback": True})
|
| 203 |
return response
|
| 204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
def extract_text_from_pdf(self, pdf_content):
|
| 206 |
"""Extract text content from PDF bytes with OCR fallback"""
|
| 207 |
try:
|
|
|
|
| 276 |
|
| 277 |
def generate_response(self, user_message, context=""):
|
| 278 |
"""Generate response using Juno AI prompts"""
|
| 279 |
+
# NEWLY ADDED: Check for name queries first
|
| 280 |
+
if self._check_for_name_query(user_message):
|
| 281 |
+
if self.user_name:
|
| 282 |
+
response = f"Your name is {self.user_name}! I remember when you told me."
|
| 283 |
+
self.chat_history.append({"user": user_message, "bot": response, "timestamp": datetime.now().isoformat()})
|
| 284 |
+
return response
|
| 285 |
+
else:
|
| 286 |
+
response = "I don't know your name yet. Would you like to tell me what it is?"
|
| 287 |
+
self.chat_history.append({"user": user_message, "bot": response, "timestamp": datetime.now().isoformat()})
|
| 288 |
+
return response
|
| 289 |
+
|
| 290 |
def _generate():
|
| 291 |
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 292 |
conversation_history = []
|
|
|
|
| 294 |
for exchange in self.chat_history[-3:]:
|
| 295 |
if not exchange.get('fallback', False):
|
| 296 |
conversation_history.append({'user': exchange['user'], 'bot': exchange['bot'], 'timestamp': exchange.get('timestamp', '')})
|
| 297 |
+
|
| 298 |
+
# NEWLY ADDED: Include user name in prompt context
|
| 299 |
+
user_context = ""
|
| 300 |
+
if self.user_name:
|
| 301 |
+
user_context = f"\nUSER NAME: {self.user_name} (remember to address them personally)"
|
| 302 |
+
|
| 303 |
+
base_prompt = self.prompts.get_conversation_prompt(user_message=user_message, context=context, conversation_history=conversation_history, memory_context=self.memory)
|
| 304 |
+
prompt = base_prompt + user_context
|
| 305 |
return model.generate_content(prompt).text
|
| 306 |
|
| 307 |
try:
|
| 308 |
bot_response = self._retry_with_backoff(_generate)
|
| 309 |
self.chat_history.append({"user": user_message, "bot": bot_response, "timestamp": datetime.now().isoformat()})
|
| 310 |
self.update_memory(user_message, bot_response)
|
| 311 |
+
# NEWLY ADDED: Extract name from conversation
|
| 312 |
+
self._extract_name_from_message(user_message, bot_response)
|
| 313 |
return bot_response
|
| 314 |
except (ResourceExhausted, GoogleAPIError):
|
| 315 |
return self._fallback_response(user_message)
|
|
|
|
| 361 |
|
| 362 |
def generate_rag_response(self, user_query, context, sources=None):
|
| 363 |
"""Generate RAG response using Juno AI prompts"""
|
| 364 |
+
# NEWLY ADDED: Check for name queries first
|
| 365 |
+
if self._check_for_name_query(user_query):
|
| 366 |
+
if self.user_name:
|
| 367 |
+
return f"Your name is {self.user_name}! I remember when you told me."
|
| 368 |
+
else:
|
| 369 |
+
return "I don't know your name yet. Would you like to tell me what it is?"
|
| 370 |
+
|
| 371 |
def _generate_rag():
|
| 372 |
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 373 |
context_chunks = [context[i:i+2000] for i in range(0, len(context), 2000)]
|
| 374 |
+
|
| 375 |
+
# NEWLY ADDED: Include user name in RAG prompt
|
| 376 |
+
user_context = ""
|
| 377 |
+
if self.user_name:
|
| 378 |
+
user_context = f"\nUSER NAME: {self.user_name} (address them personally)"
|
| 379 |
+
|
| 380 |
+
base_prompt = self.prompts.get_rag_response_prompt(user_query=user_query, retrieved_chunks=context_chunks[:3], source_info=sources)
|
| 381 |
+
prompt = base_prompt + user_context
|
| 382 |
return model.generate_content(prompt).text
|
| 383 |
|
| 384 |
try:
|
| 385 |
response = self._retry_with_backoff(_generate_rag)
|
| 386 |
+
# NEWLY ADDED: Extract name from RAG conversations too
|
| 387 |
+
self._extract_name_from_message(user_query, response)
|
| 388 |
return response
|
| 389 |
except (ResourceExhausted, GoogleAPIError):
|
| 390 |
return self._fallback_response(user_query)
|
|
|
|
| 434 |
|
| 435 |
def generate_streaming_response(self, user_message, context=""):
|
| 436 |
"""Generate streaming response using Juno AI prompts"""
|
| 437 |
+
# NEWLY ADDED: Check for name queries first
|
| 438 |
+
if self._check_for_name_query(user_message):
|
| 439 |
+
if self.user_name:
|
| 440 |
+
return f"Your name is {self.user_name}! I remember when you told me."
|
| 441 |
+
else:
|
| 442 |
+
return "I don't know your name yet. Would you like to tell me what it is?"
|
| 443 |
+
|
| 444 |
def _generate_stream():
|
| 445 |
model = genai.GenerativeModel(GENERATIVE_MODEL)
|
| 446 |
+
|
| 447 |
+
# NEWLY ADDED: Include user name in streaming prompt
|
| 448 |
+
user_context = ""
|
| 449 |
+
if self.user_name:
|
| 450 |
+
user_context = f"\nUSER NAME: {self.user_name} (address them personally)"
|
| 451 |
+
|
| 452 |
+
base_prompt = self.prompts.get_streaming_response_prompt(user_message, context)
|
| 453 |
+
prompt = base_prompt + user_context
|
| 454 |
return model.generate_content(prompt, stream=True)
|
| 455 |
|
| 456 |
try:
|
|
|
|
| 554 |
def get_memory():
|
| 555 |
return jsonify({
|
| 556 |
'memory': chatbot.memory,
|
| 557 |
+
'user_name': chatbot.user_name, # NEWLY ADDED: Include user name
|
| 558 |
+
'user_details': chatbot.user_details, # NEWLY ADDED: Include user details
|
| 559 |
'chat_history_length': len(chatbot.chat_history),
|
| 560 |
'has_vectorstore': chatbot.vectorstore is not None,
|
| 561 |
'session_id': chatbot.session_id
|
|
|
|
| 642 |
|
| 643 |
chatbot.chat_history.append({"user": user_message, "bot": full_response, "timestamp": datetime.now().isoformat()})
|
| 644 |
chatbot.update_memory(user_message, full_response)
|
| 645 |
+
# NEWLY ADDED: Extract name from streaming responses
|
| 646 |
+
chatbot._extract_name_from_message(user_message, full_response)
|
| 647 |
|
| 648 |
return jsonify({
|
| 649 |
'response': full_response,
|
|
|
|
| 745 |
logging.error(f"Error in /api/messages/{message_index}/edit: {e}", exc_info=True)
|
| 746 |
return jsonify({'error': 'An internal server error occurred.'}), 500
|
| 747 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 748 |
if __name__ == '__main__':
|
| 749 |
logging.info("🚀 Starting Juno AI Server...")
|
| 750 |
logging.info("🤖 Advanced AI Assistant with Document Processing, Web Scraping, and Memory")
|
| 751 |
logging.info("🌟 Powered by Juno AI Prompts System")
|
| 752 |
+
logging.info("🧠 Enhanced with User Name Memory")
|
| 753 |
port = int(os.environ.get("PORT", 7860))
|
| 754 |
app.run(debug=False, host='0.0.0.0', port=port)
|