Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1764,7 +1764,36 @@ async def process_incoming_message(from_number: str, msg: dict):
|
|
1764 |
# Handle voice messages FIRST - before checking message_body
|
1765 |
if message_type in ['audio', 'voice'] or media_type == 'audio':
|
1766 |
logger.info(f"[Process] Processing voice message from {from_number}")
|
1767 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1768 |
return
|
1769 |
|
1770 |
# For text messages, check if body exists
|
@@ -1773,108 +1802,69 @@ async def process_incoming_message(from_number: str, msg: dict):
|
|
1773 |
return
|
1774 |
|
1775 |
message_body = message_body.strip()
|
1776 |
-
|
1777 |
logger.info(f"[Process] Processing {message_type} message from {from_number}: {message_body}")
|
1778 |
|
1779 |
-
# --- NEW: Recognize 'all products' queries ---
|
1780 |
-
all_products_phrases = [
|
1781 |
-
'all products', 'show all products', 'i want all the product information',
|
1782 |
-
'i need all the product information', 'i want information about all products',
|
1783 |
-
'i need information about all products',
|
1784 |
-
'مجھے تمام پروڈکٹ کے بارے میں معلومات چاہیے',
|
1785 |
-
'مجھے تمام پروڈکٹس کے بارے میں معلومات چاہئے',
|
1786 |
-
'تمام پروڈکٹس', 'تمام پروڈکٹ', 'سارے پروڈکٹس', 'سارے پروڈکٹ'
|
1787 |
-
]
|
1788 |
-
def normalize(text):
|
1789 |
-
return re.sub(r'[^\w\s\u0600-\u06FF]', '', text).lower().strip()
|
1790 |
-
normalized_msg = normalize(message_body)
|
1791 |
-
if any(phrase in normalized_msg for phrase in all_products_phrases):
|
1792 |
-
logger.info(f"[Process] Detected 'all products' query: '{message_body}'")
|
1793 |
-
await display_all_products(from_number)
|
1794 |
-
return
|
1795 |
-
|
1796 |
# Get user context
|
1797 |
user_context = context_manager.get_context(from_number)
|
1798 |
current_state = user_context.get('current_state', 'main_menu')
|
1799 |
-
|
1800 |
-
# Update context with last message for intelligent responses
|
1801 |
context_manager.update_context(from_number, last_message=message_body)
|
1802 |
-
|
1803 |
-
# Debug logging
|
1804 |
logger.info(f"[Process] Current state: {current_state}, Message: '{message_body}' from {from_number}")
|
1805 |
-
|
1806 |
-
# Handle text messages
|
1807 |
if not message_body:
|
1808 |
return
|
1809 |
-
|
1810 |
-
#
|
1811 |
reply_language = 'en' # Default to English
|
1812 |
try:
|
1813 |
detected_lang = detect(message_body)
|
1814 |
logger.info(f"[Process] Raw detected language: {detected_lang}")
|
1815 |
-
|
1816 |
-
# STRICTLY ENGLISH OR URDU ONLY - REJECT ALL OTHER LANGUAGES
|
1817 |
if detected_lang in ['en', 'ur']:
|
1818 |
reply_language = detected_lang
|
1819 |
logger.info(f"[Process] Valid language detected: {detected_lang}")
|
1820 |
else:
|
1821 |
-
# Reject any other language and force to English
|
1822 |
reply_language = 'en'
|
1823 |
logger.warning(f"[Process] Invalid language '{detected_lang}' detected - forcing to English")
|
1824 |
-
|
1825 |
-
# Check if text contains Urdu/Arabic characters or Islamic greetings
|
1826 |
urdu_arabic_pattern = re.compile(r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]')
|
1827 |
islamic_greetings = ['assalamu', 'assalam', 'salam', 'salaam', 'adaab', 'namaste', 'khuda', 'allah']
|
1828 |
-
|
1829 |
has_urdu_chars = bool(urdu_arabic_pattern.search(message_body))
|
1830 |
has_islamic_greeting = any(greeting in message_body.lower() for greeting in islamic_greetings)
|
1831 |
-
|
1832 |
if has_urdu_chars or has_islamic_greeting:
|
1833 |
detected_lang = 'ur'
|
1834 |
reply_language = 'ur'
|
1835 |
logger.info(f"[Process] Overriding language detection to Urdu due to Arabic/Urdu characters or Islamic greeting")
|
1836 |
-
|
1837 |
logger.info(f"[Process] Final language set to: {reply_language}")
|
1838 |
-
|
1839 |
except Exception as e:
|
1840 |
logger.warning(f"[Process] Language detection failed: {e}, defaulting to English")
|
1841 |
reply_language = 'en'
|
1842 |
-
|
1843 |
-
#
|
1844 |
-
|
1845 |
-
|
1846 |
-
if
|
1847 |
-
|
1848 |
-
|
1849 |
-
|
1850 |
-
|
1851 |
-
|
1852 |
-
|
1853 |
-
|
1854 |
-
|
1855 |
-
welcome_msg = (
|
1856 |
-
"🩺 *اپیکس بائیوٹیکل ویٹرنری اسسٹنٹ*\n\n"
|
1857 |
-
"آپ کا خیر مقدم ہے! میں آپ کی ویٹرنری مصنوعات کے بارے میں مدد کر سکتا ہوں۔\n\n"
|
1858 |
-
"📋 *مین مینو:*\n"
|
1859 |
-
"1️⃣ مصنوعات تلاش کریں\n"
|
1860 |
-
"2️⃣ زمرے براؤز کریں\n"
|
1861 |
-
"3️⃣ کیٹلاگ ڈاؤن لوڈ کریں\n"
|
1862 |
-
"4️⃣ اے آئی چیٹ موڈ\n\n"
|
1863 |
-
"💬 اپنا انتخاب لکھیں یا 'main' لکھ کر مین مینو پر واپس جائیں۔"
|
1864 |
-
)
|
1865 |
-
else:
|
1866 |
-
welcome_msg = generate_veterinary_welcome_message()
|
1867 |
-
|
1868 |
-
send_whatsjet_message(from_number, welcome_msg)
|
1869 |
-
context_manager.update_context(
|
1870 |
-
from_number,
|
1871 |
-
current_state='main_menu',
|
1872 |
-
current_menu='main_menu',
|
1873 |
-
current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values()),
|
1874 |
-
reply_language=reply_language
|
1875 |
)
|
1876 |
-
|
1877 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1878 |
# 🎯 PRIORITY 1: Navigation commands - work from ANY state
|
1879 |
# Check for "main" command - now works for both text and voice
|
1880 |
if current_state != 'main_menu' and current_state != 'ai_chat_mode': # Only check for main if not already in main menu and not in AI chat mode
|
@@ -2184,42 +2174,56 @@ async def handle_general_query_with_ai(from_number: str, query: str, user_contex
|
|
2184 |
target_species = product.get('Target Species', 'N/A')
|
2185 |
products_context += f"{i}. {product_name} - {category} ({target_species})\n"
|
2186 |
|
2187 |
-
#
|
2188 |
prompt = f"""
|
2189 |
-
You are
|
2190 |
|
2191 |
-
|
2192 |
|
2193 |
-
|
2194 |
{products_context}
|
2195 |
|
2196 |
-
|
2197 |
-
|
2198 |
-
|
2199 |
-
-
|
2200 |
-
-
|
2201 |
-
-
|
2202 |
-
-
|
2203 |
-
|
2204 |
-
|
2205 |
-
|
2206 |
-
- Provide
|
2207 |
-
|
2208 |
-
|
2209 |
-
-
|
2210 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2211 |
- Always include navigation instructions
|
2212 |
-
-
|
2213 |
-
-
|
|
|
2214 |
|
2215 |
-
IMPORTANT:
|
2216 |
"""
|
2217 |
|
2218 |
response = openai.ChatCompletion.create(
|
2219 |
model="gpt-4o",
|
2220 |
messages=[{"role": "user", "content": prompt}],
|
2221 |
-
temperature=0.
|
2222 |
-
max_tokens=
|
2223 |
)
|
2224 |
|
2225 |
ai_response = response.choices[0].message.content.strip()
|
@@ -2331,39 +2335,58 @@ IMPORTANT: Always respond in a way that shows you understand the user's intent a
|
|
2331 |
category = product.get('Category', 'N/A')
|
2332 |
products_context += f"{i}. {product_name} - {category}\n"
|
2333 |
|
2334 |
-
#
|
2335 |
prompt = f"""
|
2336 |
-
You are
|
2337 |
-
Always answer in a clear, accurate, and helpful manner.
|
2338 |
|
2339 |
-
|
2340 |
-
|
2341 |
-
|
2342 |
|
2343 |
-
|
2344 |
{products_context}
|
2345 |
|
2346 |
-
|
2347 |
-
|
2348 |
-
|
2349 |
-
|
2350 |
-
|
2351 |
-
|
2352 |
-
|
2353 |
-
|
2354 |
-
|
2355 |
-
-
|
2356 |
-
-
|
2357 |
-
-
|
2358 |
-
-
|
2359 |
-
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2360 |
"""
|
2361 |
|
2362 |
response = openai.ChatCompletion.create(
|
2363 |
model="gpt-4o",
|
2364 |
messages=[{"role": "user", "content": prompt}],
|
2365 |
-
temperature=0.
|
2366 |
-
max_tokens=
|
2367 |
)
|
2368 |
|
2369 |
ai_response = response.choices[0].message.content.strip()
|
|
|
1764 |
# Handle voice messages FIRST - before checking message_body
|
1765 |
if message_type in ['audio', 'voice'] or media_type == 'audio':
|
1766 |
logger.info(f"[Process] Processing voice message from {from_number}")
|
1767 |
+
# Extract transcription (simulate as if already transcribed for this logic)
|
1768 |
+
transcribed_text = msg.get('transcribed_text') or ''
|
1769 |
+
# Only use menu navigation logic for strict commands
|
1770 |
+
menu_commands = ['main', 'menu', 'start', 'home', 'back', '1', '2', '3', '4', '5']
|
1771 |
+
if transcribed_text.lower().strip() in menu_commands:
|
1772 |
+
# Existing menu navigation logic (unchanged)
|
1773 |
+
if reply_language == 'ur':
|
1774 |
+
welcome_msg = (
|
1775 |
+
"🤖 ویٹرنری ورچوئل اسسٹنٹ\n\n"
|
1776 |
+
"آپ مجھ سے پوچھ سکتے ہیں:\n"
|
1777 |
+
"* ویٹرنری سوالات\n"
|
1778 |
+
"* پروڈکٹ کی سفارشات\n"
|
1779 |
+
"* علاج کے مشورے\n"
|
1780 |
+
"* عمومی معلومات\n\n"
|
1781 |
+
"💬 'main' لکھ کر مین مینو پر واپس جائیں۔"
|
1782 |
+
)
|
1783 |
+
else:
|
1784 |
+
welcome_msg = generate_veterinary_welcome_message()
|
1785 |
+
send_whatsjet_message(from_number, welcome_msg)
|
1786 |
+
context_manager.update_context(
|
1787 |
+
from_number,
|
1788 |
+
current_state='main_menu',
|
1789 |
+
current_menu='main_menu',
|
1790 |
+
current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values()),
|
1791 |
+
reply_language=reply_language
|
1792 |
+
)
|
1793 |
+
return
|
1794 |
+
# All other voice queries go to OpenAI/gpt-4o
|
1795 |
+
user_context = context_manager.get_context(from_number)
|
1796 |
+
await handle_general_query_with_ai(from_number, transcribed_text, user_context, reply_language)
|
1797 |
return
|
1798 |
|
1799 |
# For text messages, check if body exists
|
|
|
1802 |
return
|
1803 |
|
1804 |
message_body = message_body.strip()
|
|
|
1805 |
logger.info(f"[Process] Processing {message_type} message from {from_number}: {message_body}")
|
1806 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1807 |
# Get user context
|
1808 |
user_context = context_manager.get_context(from_number)
|
1809 |
current_state = user_context.get('current_state', 'main_menu')
|
|
|
|
|
1810 |
context_manager.update_context(from_number, last_message=message_body)
|
|
|
|
|
1811 |
logger.info(f"[Process] Current state: {current_state}, Message: '{message_body}' from {from_number}")
|
1812 |
+
|
|
|
1813 |
if not message_body:
|
1814 |
return
|
1815 |
+
|
1816 |
+
# LANGUAGE DETECTION FOR TEXT MESSAGES - STRICTLY ENGLISH OR URDU ONLY
|
1817 |
reply_language = 'en' # Default to English
|
1818 |
try:
|
1819 |
detected_lang = detect(message_body)
|
1820 |
logger.info(f"[Process] Raw detected language: {detected_lang}")
|
|
|
|
|
1821 |
if detected_lang in ['en', 'ur']:
|
1822 |
reply_language = detected_lang
|
1823 |
logger.info(f"[Process] Valid language detected: {detected_lang}")
|
1824 |
else:
|
|
|
1825 |
reply_language = 'en'
|
1826 |
logger.warning(f"[Process] Invalid language '{detected_lang}' detected - forcing to English")
|
|
|
|
|
1827 |
urdu_arabic_pattern = re.compile(r'[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]')
|
1828 |
islamic_greetings = ['assalamu', 'assalam', 'salam', 'salaam', 'adaab', 'namaste', 'khuda', 'allah']
|
|
|
1829 |
has_urdu_chars = bool(urdu_arabic_pattern.search(message_body))
|
1830 |
has_islamic_greeting = any(greeting in message_body.lower() for greeting in islamic_greetings)
|
|
|
1831 |
if has_urdu_chars or has_islamic_greeting:
|
1832 |
detected_lang = 'ur'
|
1833 |
reply_language = 'ur'
|
1834 |
logger.info(f"[Process] Overriding language detection to Urdu due to Arabic/Urdu characters or Islamic greeting")
|
|
|
1835 |
logger.info(f"[Process] Final language set to: {reply_language}")
|
|
|
1836 |
except Exception as e:
|
1837 |
logger.warning(f"[Process] Language detection failed: {e}, defaulting to English")
|
1838 |
reply_language = 'en'
|
1839 |
+
|
1840 |
+
# Only use keyword logic for strict menu navigation
|
1841 |
+
menu_commands = ['main', 'menu', 'start', 'home', 'back', '1', '2', '3', '4', '5']
|
1842 |
+
if message_body.lower().strip() in menu_commands:
|
1843 |
+
if reply_language == 'ur':
|
1844 |
+
welcome_msg = (
|
1845 |
+
"🤖 ویٹرنری ورچوئل اسسٹنٹ\n\n"
|
1846 |
+
"آپ مجھ سے پوچھ سکتے ہیں:\n"
|
1847 |
+
"* ویٹرنری سوالات\n"
|
1848 |
+
"* پروڈکٹ کی سفارشات\n"
|
1849 |
+
"* علاج کے مشورے\n"
|
1850 |
+
"* عمومی معلومات\n\n"
|
1851 |
+
"💬 'main' لکھ کر مین مینو پر واپس جائیں۔"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1852 |
)
|
1853 |
+
else:
|
1854 |
+
welcome_msg = generate_veterinary_welcome_message()
|
1855 |
+
send_whatsjet_message(from_number, welcome_msg)
|
1856 |
+
context_manager.update_context(
|
1857 |
+
from_number,
|
1858 |
+
current_state='main_menu',
|
1859 |
+
current_menu='main_menu',
|
1860 |
+
current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values()),
|
1861 |
+
reply_language=reply_language
|
1862 |
+
)
|
1863 |
+
return
|
1864 |
+
# All other queries: always use OpenAI/gpt-4o for intelligent response
|
1865 |
+
await handle_general_query_with_ai(from_number, message_body, user_context, reply_language)
|
1866 |
+
return
|
1867 |
+
|
1868 |
# 🎯 PRIORITY 1: Navigation commands - work from ANY state
|
1869 |
# Check for "main" command - now works for both text and voice
|
1870 |
if current_state != 'main_menu' and current_state != 'ai_chat_mode': # Only check for main if not already in main menu and not in AI chat mode
|
|
|
2174 |
target_species = product.get('Target Species', 'N/A')
|
2175 |
products_context += f"{i}. {product_name} - {category} ({target_species})\n"
|
2176 |
|
2177 |
+
# Expert-level AI prompt for comprehensive veterinary assistance
|
2178 |
prompt = f"""
|
2179 |
+
You are an EXPERT veterinary pharmaceutical assistant for Apex Biotical, with deep knowledge of veterinary medicine, animal health, and pharmaceutical products. You help users on WhatsApp with professional, accurate, and context-aware responses.
|
2180 |
|
2181 |
+
USER QUERY: "{query}"
|
2182 |
|
2183 |
+
AVAILABLE PRODUCTS DATABASE:
|
2184 |
{products_context}
|
2185 |
|
2186 |
+
EXPERT ANALYSIS FRAMEWORK:
|
2187 |
+
|
2188 |
+
1. **QUERY TYPE DETECTION:**
|
2189 |
+
- COUNT/QUANTITY queries: "how many", "count", "total", "number of"
|
2190 |
+
- PRODUCT INQUIRIES: specific product names, categories, or therapeutic areas
|
2191 |
+
- COMPANY INQUIRIES: "apex", "company", "about", "who are you"
|
2192 |
+
- VETERINARY ADVICE: medical questions, treatment recommendations, dosage
|
2193 |
+
- GENERAL QUESTIONS: greetings, navigation, help requests
|
2194 |
+
|
2195 |
+
2. **CONTEXT-AWARE RESPONSE STRATEGY:**
|
2196 |
+
- For COUNT queries: Provide exact numbers with category breakdowns
|
2197 |
+
- For PRODUCT queries: List relevant products with therapeutic benefits, target species, and key features
|
2198 |
+
- For COMPANY queries: Professional company overview with expertise areas
|
2199 |
+
- For VETERINARY ADVICE: Evidence-based recommendations with product suggestions
|
2200 |
+
- For GENERAL queries: Helpful guidance with menu navigation
|
2201 |
+
|
2202 |
+
3. **EXPERT KNOWLEDGE INTEGRATION:**
|
2203 |
+
- Veterinary pharmacology and therapeutics
|
2204 |
+
- Animal health and disease management
|
2205 |
+
- Pharmaceutical product applications
|
2206 |
+
- Professional veterinary communication
|
2207 |
+
- Regulatory and safety considerations
|
2208 |
+
|
2209 |
+
RESPONSE GUIDELINES:
|
2210 |
+
- Be PROFESSIONAL, EXPERT, and HELPFUL
|
2211 |
+
- Use appropriate veterinary terminology
|
2212 |
+
- Include relevant emojis for clarity
|
2213 |
+
- Provide accurate, evidence-based information
|
2214 |
- Always include navigation instructions
|
2215 |
+
- Show understanding of user's intent and context
|
2216 |
+
- Be concise but comprehensive
|
2217 |
+
- Maintain professional veterinary standards
|
2218 |
|
2219 |
+
IMPORTANT: Demonstrate expert-level veterinary knowledge while being accessible and helpful. Always provide accurate information from the database and professional veterinary guidance.
|
2220 |
"""
|
2221 |
|
2222 |
response = openai.ChatCompletion.create(
|
2223 |
model="gpt-4o",
|
2224 |
messages=[{"role": "user", "content": prompt}],
|
2225 |
+
temperature=0.3, # Lower temperature for more consistent, expert responses
|
2226 |
+
max_tokens=600 # Increased for more comprehensive expert responses
|
2227 |
)
|
2228 |
|
2229 |
ai_response = response.choices[0].message.content.strip()
|
|
|
2335 |
category = product.get('Category', 'N/A')
|
2336 |
products_context += f"{i}. {product_name} - {category}\n"
|
2337 |
|
2338 |
+
# Expert-level prompt for comprehensive veterinary assistance
|
2339 |
prompt = f"""
|
2340 |
+
You are an EXPERT veterinary pharmaceutical assistant for Apex Biotical, with deep knowledge of veterinary medicine, animal health, and pharmaceutical products. You help users on WhatsApp with professional, accurate, and context-aware responses.
|
|
|
2341 |
|
2342 |
+
USER QUERY: "{query}"
|
2343 |
+
CURRENT STATE: {current_state}
|
2344 |
+
CURRENT PRODUCT: {current_product.get('Product Name', 'None') if current_product else 'None'}
|
2345 |
|
2346 |
+
AVAILABLE PRODUCTS:
|
2347 |
{products_context}
|
2348 |
|
2349 |
+
EXPERT ANALYSIS FRAMEWORK:
|
2350 |
+
|
2351 |
+
1. **QUERY TYPE DETECTION:**
|
2352 |
+
- COUNT/QUANTITY queries: "how many", "count", "total", "number of"
|
2353 |
+
- PRODUCT INQUIRIES: specific product names, categories, or therapeutic areas
|
2354 |
+
- COMPANY INQUIRIES: "apex", "company", "about", "who are you"
|
2355 |
+
- VETERINARY ADVICE: medical questions, treatment recommendations, dosage
|
2356 |
+
- GENERAL QUESTIONS: greetings, navigation, help requests
|
2357 |
+
|
2358 |
+
2. **CONTEXT-AWARE RESPONSE STRATEGY:**
|
2359 |
+
- For COUNT queries: Provide exact numbers with category breakdowns
|
2360 |
+
- For PRODUCT queries: List relevant products with therapeutic benefits, target species, and key features
|
2361 |
+
- For COMPANY queries: Professional company overview with expertise areas
|
2362 |
+
- For VETERINARY ADVICE: Evidence-based recommendations with product suggestions
|
2363 |
+
- For GENERAL queries: Helpful guidance with menu navigation
|
2364 |
+
|
2365 |
+
3. **EXPERT KNOWLEDGE INTEGRATION:**
|
2366 |
+
- Veterinary pharmacology and therapeutics
|
2367 |
+
- Animal health and disease management
|
2368 |
+
- Pharmaceutical product applications
|
2369 |
+
- Professional veterinary communication
|
2370 |
+
- Regulatory and safety considerations
|
2371 |
+
|
2372 |
+
RESPONSE GUIDELINES:
|
2373 |
+
- Be PROFESSIONAL, EXPERT, and HELPFUL
|
2374 |
+
- Use appropriate veterinary terminology
|
2375 |
+
- Include relevant emojis for clarity
|
2376 |
+
- Provide accurate, evidence-based information
|
2377 |
+
- Always include navigation instructions
|
2378 |
+
- Show understanding of user's intent and context
|
2379 |
+
- Be concise but comprehensive
|
2380 |
+
- Maintain professional veterinary standards
|
2381 |
+
|
2382 |
+
IMPORTANT: Demonstrate expert-level veterinary knowledge while being accessible and helpful. Always provide accurate information from the database and professional veterinary guidance.
|
2383 |
"""
|
2384 |
|
2385 |
response = openai.ChatCompletion.create(
|
2386 |
model="gpt-4o",
|
2387 |
messages=[{"role": "user", "content": prompt}],
|
2388 |
+
temperature=0.3, # Lower temperature for more consistent, expert responses
|
2389 |
+
max_tokens=400 # Increased for more comprehensive expert responses
|
2390 |
)
|
2391 |
|
2392 |
ai_response = response.choices[0].message.content.strip()
|