Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1893,7 +1893,14 @@ async def process_incoming_message(from_number: str, msg: dict):
|
|
| 1893 |
await handle_general_query_with_ai(from_number, message_body, user_context, reply_language)
|
| 1894 |
return
|
| 1895 |
|
| 1896 |
-
# π― PRIORITY 5:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1897 |
# This ensures users can say product names like "hydropex", "respira aid plus", etc. from any menu
|
| 1898 |
logger.info(f"[Process] Checking for product name in message: '{message_body}' from state: {current_state}")
|
| 1899 |
products = get_veterinary_product_matches(message_body)
|
|
@@ -1988,7 +1995,7 @@ async def process_incoming_message(from_number: str, msg: dict):
|
|
| 1988 |
# Simple one-liner for wrong queries
|
| 1989 |
send_whatsjet_message(from_number, "β Please correct your question or type 'main' to go to main menu.")
|
| 1990 |
|
| 1991 |
-
# π― PRIORITY
|
| 1992 |
await handle_intelligent_product_inquiry(from_number, message_body, user_context, reply_language)
|
| 1993 |
|
| 1994 |
except Exception as e:
|
|
@@ -2030,6 +2037,12 @@ IMPORTANT INSTRUCTIONS:
|
|
| 2030 |
6. Use emojis and bullet points for better readability.
|
| 2031 |
7. If you don't have specific information, say so clearly and suggest alternatives.
|
| 2032 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2033 |
Available Products Database: {products_df.to_dict('records') if products_df is not None else 'No products loaded'}
|
| 2034 |
|
| 2035 |
RESPONSE FORMAT:
|
|
@@ -2037,6 +2050,7 @@ RESPONSE FORMAT:
|
|
| 2037 |
- Use emojis sparingly but effectively
|
| 2038 |
- Avoid long titles or headers
|
| 2039 |
- Focus on providing accurate, helpful information
|
|
|
|
| 2040 |
"""
|
| 2041 |
response = openai.ChatCompletion.create(
|
| 2042 |
model="gpt-4o",
|
|
@@ -2047,7 +2061,21 @@ RESPONSE FORMAT:
|
|
| 2047 |
ai_response = response.choices[0].message.content.strip()
|
| 2048 |
if reply_language == 'ur':
|
| 2049 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2050 |
translated_response = GoogleTranslator(source='auto', target='ur').translate(ai_response)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2051 |
send_whatsjet_message(from_number, translated_response)
|
| 2052 |
except Exception as e:
|
| 2053 |
logger.error(f"[AI] Translation error: {e}")
|
|
@@ -2575,9 +2603,15 @@ Response:
|
|
| 2575 |
# Get all product and category names
|
| 2576 |
product_names = [str(p.get('Product Name', '')) for p in all_products if p.get('Product Name')]
|
| 2577 |
category_names = list(set([str(p.get('Category', '')) for p in all_products if p.get('Category')]))
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2578 |
translated_response = GoogleTranslator(source='auto', target='ur').translate(ai_response)
|
| 2579 |
-
|
| 2580 |
-
|
|
|
|
|
|
|
| 2581 |
send_whatsjet_message(from_number, translated_response)
|
| 2582 |
except Exception as e:
|
| 2583 |
logger.error(f"[AI] Translation error: {e}")
|
|
@@ -3749,29 +3783,6 @@ async def handle_intelligent_product_inquiry(from_number: str, query: str, user_
|
|
| 3749 |
# The actual sending of product details should be handled by the caller
|
| 3750 |
return selected_product
|
| 3751 |
else:
|
| 3752 |
-
# Check for specific query types before falling back to generic response
|
| 3753 |
-
query_lower = query.lower().strip()
|
| 3754 |
-
|
| 3755 |
-
# Check for company/about queries
|
| 3756 |
-
if any(keyword in query_lower for keyword in ['apex', 'company', 'about', 'who', 'what is']):
|
| 3757 |
-
# Use OpenAI for company information
|
| 3758 |
-
await handle_general_query_with_ai(from_number, query, user_context, reply_language)
|
| 3759 |
-
return
|
| 3760 |
-
|
| 3761 |
-
# Check for product-specific questions (mode of action, dosage, etc.)
|
| 3762 |
-
product_question_keywords = ['mode of action', 'dosage', 'administration', 'composition', 'indications', 'precautions', 'storage', 'how to use', 'side effects']
|
| 3763 |
-
if any(keyword in query_lower for keyword in product_question_keywords):
|
| 3764 |
-
# Use OpenAI for product-specific questions
|
| 3765 |
-
await handle_general_query_with_ai(from_number, query, user_context, reply_language)
|
| 3766 |
-
return
|
| 3767 |
-
|
| 3768 |
-
# Check for general veterinary questions
|
| 3769 |
-
veterinary_keywords = ['weather', 'temperature', 'disease', 'symptoms', 'treatment', 'prevention', 'vaccination', 'nutrition', 'health']
|
| 3770 |
-
if any(keyword in query_lower for keyword in veterinary_keywords):
|
| 3771 |
-
# Simple redirect for non-veterinary topics
|
| 3772 |
-
send_whatsjet_message(from_number, "β Please ask the correct question related to Apex Biotical Solutions or type 'main' to go to main menu.")
|
| 3773 |
-
return
|
| 3774 |
-
|
| 3775 |
# Simple one-liner for wrong queries
|
| 3776 |
send_whatsjet_message(from_number, "β Please correct your question or type 'main' to go to main menu.")
|
| 3777 |
except Exception as e:
|
|
@@ -3812,10 +3823,34 @@ async def handle_contact_request(from_number: str):
|
|
| 3812 |
|
| 3813 |
# Helper for restoring English terms in translations
|
| 3814 |
def restore_english_terms(translated_text, original_text, product_names, category_names):
|
| 3815 |
-
|
| 3816 |
-
|
| 3817 |
-
|
| 3818 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3819 |
return translated_text
|
| 3820 |
|
| 3821 |
if __name__ == "__main__":
|
|
|
|
| 1893 |
await handle_general_query_with_ai(from_number, message_body, user_context, reply_language)
|
| 1894 |
return
|
| 1895 |
|
| 1896 |
+
# π― PRIORITY 5: Check for product-specific questions (mode of action, dosage, etc.)
|
| 1897 |
+
product_question_keywords = ['mode of action', 'dosage', 'administration', 'composition', 'indications', 'precautions', 'storage', 'how to use', 'side effects']
|
| 1898 |
+
if any(keyword in query_lower for keyword in product_question_keywords):
|
| 1899 |
+
# Use OpenAI for product-specific questions
|
| 1900 |
+
await handle_general_query_with_ai(from_number, message_body, user_context, reply_language)
|
| 1901 |
+
return
|
| 1902 |
+
|
| 1903 |
+
# π― PRIORITY 6: Product names - works from ANY menu state
|
| 1904 |
# This ensures users can say product names like "hydropex", "respira aid plus", etc. from any menu
|
| 1905 |
logger.info(f"[Process] Checking for product name in message: '{message_body}' from state: {current_state}")
|
| 1906 |
products = get_veterinary_product_matches(message_body)
|
|
|
|
| 1995 |
# Simple one-liner for wrong queries
|
| 1996 |
send_whatsjet_message(from_number, "β Please correct your question or type 'main' to go to main menu.")
|
| 1997 |
|
| 1998 |
+
# π― PRIORITY 7: Default: treat as general query with intelligent product inquiry
|
| 1999 |
await handle_intelligent_product_inquiry(from_number, message_body, user_context, reply_language)
|
| 2000 |
|
| 2001 |
except Exception as e:
|
|
|
|
| 2037 |
6. Use emojis and bullet points for better readability.
|
| 2038 |
7. If you don't have specific information, say so clearly and suggest alternatives.
|
| 2039 |
|
| 2040 |
+
CRITICAL NAMING RULES:
|
| 2041 |
+
- ALWAYS keep company name "Apex Biotical Solutions" in English, even in Urdu responses
|
| 2042 |
+
- ALWAYS keep product names in English (e.g., "EC-Immune", "Hydropex", "Heposel")
|
| 2043 |
+
- ALWAYS keep technical terms in English when possible
|
| 2044 |
+
- Only translate descriptive text, not proper nouns or brand names
|
| 2045 |
+
|
| 2046 |
Available Products Database: {products_df.to_dict('records') if products_df is not None else 'No products loaded'}
|
| 2047 |
|
| 2048 |
RESPONSE FORMAT:
|
|
|
|
| 2050 |
- Use emojis sparingly but effectively
|
| 2051 |
- Avoid long titles or headers
|
| 2052 |
- Focus on providing accurate, helpful information
|
| 2053 |
+
- Preserve English company names and product names
|
| 2054 |
"""
|
| 2055 |
response = openai.ChatCompletion.create(
|
| 2056 |
model="gpt-4o",
|
|
|
|
| 2061 |
ai_response = response.choices[0].message.content.strip()
|
| 2062 |
if reply_language == 'ur':
|
| 2063 |
try:
|
| 2064 |
+
# Get all product and category names for restoration
|
| 2065 |
+
product_names = []
|
| 2066 |
+
category_names = []
|
| 2067 |
+
if products_df is not None and not products_df.empty:
|
| 2068 |
+
product_names = [str(p.get('Product Name', '')) for p in products_df.to_dict('records') if p.get('Product Name')]
|
| 2069 |
+
category_names = list(set([str(p.get('Category', '')) for p in products_df.to_dict('records') if p.get('Category')]))
|
| 2070 |
+
|
| 2071 |
+
# Add company names to preserve in English
|
| 2072 |
+
company_names = ['Apex Biotical Solutions', 'Apex Biotical', 'Apex']
|
| 2073 |
+
|
| 2074 |
translated_response = GoogleTranslator(source='auto', target='ur').translate(ai_response)
|
| 2075 |
+
|
| 2076 |
+
# Restore English terms including company names
|
| 2077 |
+
translated_response = restore_english_terms(translated_response, ai_response, product_names + company_names, category_names)
|
| 2078 |
+
|
| 2079 |
send_whatsjet_message(from_number, translated_response)
|
| 2080 |
except Exception as e:
|
| 2081 |
logger.error(f"[AI] Translation error: {e}")
|
|
|
|
| 2603 |
# Get all product and category names
|
| 2604 |
product_names = [str(p.get('Product Name', '')) for p in all_products if p.get('Product Name')]
|
| 2605 |
category_names = list(set([str(p.get('Category', '')) for p in all_products if p.get('Category')]))
|
| 2606 |
+
|
| 2607 |
+
# Add company names to preserve in English
|
| 2608 |
+
company_names = ['Apex Biotical Solutions', 'Apex Biotical', 'Apex']
|
| 2609 |
+
|
| 2610 |
translated_response = GoogleTranslator(source='auto', target='ur').translate(ai_response)
|
| 2611 |
+
|
| 2612 |
+
# Restore English terms including company names
|
| 2613 |
+
translated_response = restore_english_terms(translated_response, ai_response, product_names + company_names, category_names)
|
| 2614 |
+
|
| 2615 |
send_whatsjet_message(from_number, translated_response)
|
| 2616 |
except Exception as e:
|
| 2617 |
logger.error(f"[AI] Translation error: {e}")
|
|
|
|
| 3783 |
# The actual sending of product details should be handled by the caller
|
| 3784 |
return selected_product
|
| 3785 |
else:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3786 |
# Simple one-liner for wrong queries
|
| 3787 |
send_whatsjet_message(from_number, "β Please correct your question or type 'main' to go to main menu.")
|
| 3788 |
except Exception as e:
|
|
|
|
| 3823 |
|
| 3824 |
# Helper for restoring English terms in translations
|
| 3825 |
def restore_english_terms(translated_text, original_text, product_names, category_names):
|
| 3826 |
+
"""
|
| 3827 |
+
Restore English terms (company names, product names, technical terms) in translated text.
|
| 3828 |
+
This ensures that proper nouns and brand names remain in English even in Urdu responses.
|
| 3829 |
+
"""
|
| 3830 |
+
# Add common technical terms that should remain in English
|
| 3831 |
+
technical_terms = [
|
| 3832 |
+
'EC-Immune', 'Hydropex', 'Heposel', 'Respira Aid Plus', 'Bromacid',
|
| 3833 |
+
'mode of action', 'dosage', 'administration', 'composition',
|
| 3834 |
+
'veterinary', 'pharmaceutical', 'supplement', 'antibiotic'
|
| 3835 |
+
]
|
| 3836 |
+
|
| 3837 |
+
# Combine all terms that should remain in English
|
| 3838 |
+
all_english_terms = product_names + category_names + technical_terms
|
| 3839 |
+
|
| 3840 |
+
# Process each term
|
| 3841 |
+
for term in all_english_terms:
|
| 3842 |
+
if term and term.strip():
|
| 3843 |
+
# Handle case variations
|
| 3844 |
+
term_lower = term.lower()
|
| 3845 |
+
translated_lower = translated_text.lower()
|
| 3846 |
+
|
| 3847 |
+
# If the term exists in translated text but not in original, restore it
|
| 3848 |
+
if term_lower in translated_lower:
|
| 3849 |
+
# Find the actual case in the translated text and replace with original
|
| 3850 |
+
import re
|
| 3851 |
+
pattern = re.compile(re.escape(term), re.IGNORECASE)
|
| 3852 |
+
translated_text = pattern.sub(term, translated_text)
|
| 3853 |
+
|
| 3854 |
return translated_text
|
| 3855 |
|
| 3856 |
if __name__ == "__main__":
|