DreamStream-1 commited on
Commit
4e662d0
·
verified ·
1 Parent(s): 23c7b7f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -201
app.py CHANGED
@@ -1996,25 +1996,15 @@ async def process_incoming_message(from_number: str, msg: dict):
1996
 
1997
  async def handle_general_query_with_ai(from_number: str, query: str, user_context: dict, reply_language: str = 'en'):
1998
  """Handle general queries with OpenAI intelligence"""
1999
- # Force Urdu replies for Option 4
2000
  reply_language = 'ur'
2001
  logger.info(f"[AI General] Forcing reply_language to Urdu for Option 4.")
2002
-
2003
  try:
2004
- if not OPENAI_API_KEY:
2005
  send_whatsjet_message(from_number,
2006
  "❌ AI assistance is not available. Please try searching for a specific product or type 'main' for the menu.")
2007
  return
2008
-
2009
- # Create context-aware prompt
2010
  current_state = user_context.get('current_state', 'main_menu')
2011
  current_product = user_context.get('current_product')
2012
-
2013
- # --- SYSTEM PROMPT FOR GENERAL/OUT-OF-MENU QUERIES ---
2014
- # This prompt ensures the assistant answers professionally, accurately, and helpfully.
2015
- # If the query is about products, list all relevant products (not just one) with brief details.
2016
- # If the query is general, provide a concise, expert veterinary answer.
2017
- # Clarify when a query is outside the menu system and offer to return to the main menu if needed.
2018
  prompt = f"""
2019
  You are a professional veterinary product assistant for Apex Biotical, helping users on WhatsApp.
2020
  Always answer in a clear, accurate, and helpful manner.
@@ -2028,17 +2018,13 @@ If the user asks a general veterinary question, provide a concise, expert answer
2028
  If the query is outside the menu system, politely clarify and offer to return to the main menu (type 'main').
2029
  Always keep responses professional, concise, and user-friendly.
2030
  """
2031
-
2032
  response = openai.ChatCompletion.create(
2033
  model="gpt-4o",
2034
  messages=[{"role": "user", "content": prompt}],
2035
  temperature=0.7,
2036
  max_tokens=300
2037
  )
2038
-
2039
  ai_response = response.choices[0].message.content.strip()
2040
-
2041
- # Translate response if needed
2042
  if reply_language == 'ur':
2043
  try:
2044
  translated_response = GoogleTranslator(source='auto', target='ur').translate(ai_response)
@@ -2048,21 +2034,11 @@ Always keep responses professional, concise, and user-friendly.
2048
  send_whatsjet_message(from_number, ai_response)
2049
  else:
2050
  send_whatsjet_message(from_number, ai_response)
2051
-
2052
- # Add to conversation history
2053
- context_manager.add_to_history(from_number, query, ai_response)
2054
-
2055
  except Exception as e:
2056
  logger.error(f"[AI] Error handling general query: {e}")
2057
- # Instead of sending a generic error, return to main menu
2058
- welcome_msg = generate_veterinary_welcome_message()
2059
- send_whatsjet_message(from_number, welcome_msg)
2060
- context_manager.update_context(
2061
- from_number,
2062
- current_state='main_menu',
2063
- current_menu='main_menu',
2064
- current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
2065
- )
2066
 
2067
  async def handle_contact_request(from_number: str):
2068
  """Handle contact request"""
@@ -3712,181 +3688,51 @@ async def test_send_product_image(phone: str, product_name: str = "Bromacid"):
3712
  return {"error": str(e)}
3713
 
3714
  async def handle_intelligent_product_inquiry(from_number: str, query: str, user_context: dict, reply_language: str = 'en'):
3715
- """Handle product inquiry with OpenAI intelligence and media support"""
3716
  try:
3717
- # First try direct product search
3718
  products = get_veterinary_product_matches(query)
3719
-
3720
  if products:
3721
- # Check if this is a broad/category query (multiple products found)
3722
  if len(products) > 1:
3723
- # Use OpenAI to generate a professional summary and list all products
3724
- if OPENAI_API_KEY:
3725
- try:
3726
- # Create a comprehensive prompt for multiple products
3727
- products_info = []
3728
- for i, product in enumerate(products, 1):
3729
- product_name = product.get('Product Name', 'N/A')
3730
- category = product.get('Category', 'N/A')
3731
- target_species = product.get('Target Species', 'N/A')
3732
- products_info.append(f"{i}. {product_name} - {category} ({target_species})")
3733
-
3734
- products_text = "\n".join(products_info)
3735
-
3736
- prompt = f"""
3737
- You are a professional veterinary product assistant for Apex Biotical. The user asked about "{query}" and we found {len(products)} relevant products.
3738
-
3739
- Available Products:
3740
- {products_text}
3741
-
3742
- Please provide:
3743
- 1. A professional, welcoming response acknowledging their query
3744
- 2. A brief summary of what these products are for (if it's a category like "poultry products", explain the category)
3745
- 3. List all products with their numbers and brief descriptions
3746
- 4. Clear instructions on how to proceed
3747
-
3748
- Format your response professionally with emojis and clear structure. Keep it concise but informative.
3749
- """
3750
-
3751
- response = openai.ChatCompletion.create(
3752
- model="gpt-4o",
3753
- messages=[{"role": "user", "content": prompt}],
3754
- temperature=0.7,
3755
- max_tokens=400
3756
- )
3757
-
3758
- ai_response = response.choices[0].message['content'].strip()
3759
-
3760
- # Add instructions for selection
3761
- selection_instructions = (
3762
- f"\n\n💬 *To view detailed information about any product, reply with its number (1-{len(products)})*\n"
3763
- "💬 *Type 'main' to return to the main menu*"
3764
- )
3765
-
3766
- full_response = ai_response + selection_instructions
3767
-
3768
- # Translate response if needed
3769
- if reply_language == 'ur':
3770
- try:
3771
- translated_response = GoogleTranslator(source='auto', target='ur').translate(full_response)
3772
- send_whatsjet_message(from_number, translated_response)
3773
- except Exception as e:
3774
- logger.error(f"[AI] Translation error: {e}")
3775
- send_whatsjet_message(from_number, full_response)
3776
- else:
3777
- send_whatsjet_message(from_number, full_response)
3778
-
3779
- # Store the product list in context for selection handling
3780
- context_manager.update_context(
3781
- from_number,
3782
- current_state='intelligent_products_menu',
3783
- current_menu='intelligent_products_menu',
3784
- current_menu_options=[f"Product {i+1}" for i in range(len(products))],
3785
- available_products=products,
3786
- last_query=query
3787
- )
3788
-
3789
- # Add to conversation history
3790
- context_manager.add_to_history(from_number, query, full_response)
3791
- return
3792
-
3793
- except Exception as e:
3794
- logger.error(f"[AI] Error generating product summary: {e}")
3795
- # Fall back to simple listing if AI fails
3796
- pass
3797
-
3798
- # Fallback: Simple listing without AI
3799
- message = f"🔍 *Found {len(products)} products matching '{query}':*\n\n"
3800
-
3801
  for i, product in enumerate(products, 1):
3802
- product_name = product.get('Product Name', 'N/A')
3803
- category = product.get('Category', 'N/A')
3804
- target_species = product.get('Target Species', 'N/A')
3805
- message += f"{format_number_with_emoji(i)} {product_name}\n"
3806
- message += f" 📦 {category} ({target_species})\n\n"
3807
-
3808
- message += (
3809
- f"💬 *To view detailed information about any product, reply with its number (1-{len(products)})*\n"
3810
- "💬 *Type 'main' to return to the main menu*"
3811
- )
3812
-
3813
- # Translate response if needed
3814
- if reply_language == 'ur':
3815
- try:
3816
- translated_message = GoogleTranslator(source='auto', target='ur').translate(message)
3817
- send_whatsjet_message(from_number, translated_message)
3818
- except Exception as e:
3819
- logger.error(f"[AI] Translation error: {e}")
3820
- send_whatsjet_message(from_number, message)
3821
- else:
3822
- send_whatsjet_message(from_number, message)
3823
-
3824
- # Store the product list in context for selection handling
3825
- context_manager.update_context(
3826
- from_number,
3827
- current_state='intelligent_products_menu',
3828
- current_menu='intelligent_products_menu',
3829
- current_menu_options=[f"Product {i+1}" for i in range(len(products))],
3830
- available_products=products,
3831
- last_query=query
3832
- )
3833
-
3834
- # Add to conversation history
3835
- context_manager.add_to_history(from_number, query, message)
3836
-
3837
  else:
3838
- # Single product found - show detailed information with media support
3839
  selected_product = products[0]
3840
- context_manager.update_context(
3841
- from_number,
3842
- current_product=selected_product,
3843
- current_state='product_inquiry',
3844
- current_menu='product_inquiry',
3845
- current_menu_options=list(MENU_CONFIG['product_inquiry']['option_descriptions'].values())
3846
- )
3847
-
3848
- # Send product image with caption using the new function
3849
- await send_product_image_with_caption(from_number, selected_product, user_context)
3850
-
3851
- # Add to conversation history
3852
- context_manager.add_to_history(from_number, query, f"Product inquiry for {selected_product.get('Product Name', 'Unknown')}")
3853
-
3854
  else:
3855
- # Enhanced "not found" response with veterinary suggestions
3856
- message = (
3857
- "❌ *Product Not Found*\n\n"
3858
- f"🔍 *We couldn't find '{query}' in our veterinary database.*\n\n"
3859
- "💡 *Try these alternatives:*\n"
3860
- "• Check spelling (e.g., 'Hydropex' not 'Hydro pex')\n"
3861
- "• Search by symptoms (e.g., 'respiratory', 'liver support')\n"
3862
- "• Search by category (e.g., 'antibiotic', 'vitamin')\n"
3863
- "• Search by species (e.g., 'poultry', 'livestock')\n\n"
3864
- "🏥 *Popular Veterinary Products:*\n"
3865
- "• Hydropex (Electrolyte supplement)\n"
3866
- "• Heposel (Liver tonic)\n"
3867
- "• Bromacid (Respiratory support)\n"
3868
- "• Tribiotic (Antibiotic)\n"
3869
- "• Symodex (Multivitamin)\n\n"
3870
- "💬 *Type 'main' to return to main menu or try another search.*"
3871
- )
3872
-
3873
- # Translate response if needed
3874
- if reply_language == 'ur':
3875
- try:
3876
- translated_message = GoogleTranslator(source='auto', target='ur').translate(message)
3877
- send_whatsjet_message(from_number, translated_message)
3878
- except Exception as e:
3879
- logger.error(f"[AI] Translation error: {e}")
3880
- send_whatsjet_message(from_number, message)
3881
- else:
3882
- send_whatsjet_message(from_number, message)
3883
-
3884
  except Exception as e:
3885
- logger.error(f"Error in product inquiry: {e}")
3886
- # Instead of sending a generic error, return to main menu
3887
- welcome_msg = generate_veterinary_welcome_message(from_number, user_context)
3888
- send_whatsjet_message(from_number, welcome_msg)
3889
- context_manager.update_context(from_number, current_state='main_menu', current_menu='main_menu', current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values()))
3890
 
3891
  async def handle_contact_request(from_number: str):
3892
  """Handle contact request"""
@@ -3920,17 +3766,11 @@ async def handle_contact_request(from_number: str):
3920
  current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
3921
  )
3922
 
3923
- # Add this helper function near the top of the file:
3924
  def restore_english_terms(translated_text, original_text, product_names, category_names):
3925
- """
3926
- Replace Urdu-translated product/category names in translated_text with their original English from original_text.
3927
- """
3928
  for name in product_names + category_names:
3929
  if name and name.lower() in translated_text.lower() and name.lower() not in original_text.lower():
3930
- # If the English name is not in the original, skip
3931
  continue
3932
- # Replace Urdu translation with English name
3933
- # (This is a simple approach; for more accuracy, use regex or fuzzy matching)
3934
  translated_text = translated_text.replace(name, name)
3935
  return translated_text
3936
 
 
1996
 
1997
  async def handle_general_query_with_ai(from_number: str, query: str, user_context: dict, reply_language: str = 'en'):
1998
  """Handle general queries with OpenAI intelligence"""
 
1999
  reply_language = 'ur'
2000
  logger.info(f"[AI General] Forcing reply_language to Urdu for Option 4.")
 
2001
  try:
2002
+ if not openai.api_key:
2003
  send_whatsjet_message(from_number,
2004
  "❌ AI assistance is not available. Please try searching for a specific product or type 'main' for the menu.")
2005
  return
 
 
2006
  current_state = user_context.get('current_state', 'main_menu')
2007
  current_product = user_context.get('current_product')
 
 
 
 
 
 
2008
  prompt = f"""
2009
  You are a professional veterinary product assistant for Apex Biotical, helping users on WhatsApp.
2010
  Always answer in a clear, accurate, and helpful manner.
 
2018
  If the query is outside the menu system, politely clarify and offer to return to the main menu (type 'main').
2019
  Always keep responses professional, concise, and user-friendly.
2020
  """
 
2021
  response = openai.ChatCompletion.create(
2022
  model="gpt-4o",
2023
  messages=[{"role": "user", "content": prompt}],
2024
  temperature=0.7,
2025
  max_tokens=300
2026
  )
 
2027
  ai_response = response.choices[0].message.content.strip()
 
 
2028
  if reply_language == 'ur':
2029
  try:
2030
  translated_response = GoogleTranslator(source='auto', target='ur').translate(ai_response)
 
2034
  send_whatsjet_message(from_number, ai_response)
2035
  else:
2036
  send_whatsjet_message(from_number, ai_response)
2037
+ if context_manager:
2038
+ context_manager.add_to_history(from_number, query, ai_response)
 
 
2039
  except Exception as e:
2040
  logger.error(f"[AI] Error handling general query: {e}")
2041
+ send_whatsjet_message(from_number, "❌ AI Assistant encountered an error. Please try again or type 'main' to return to main menu.")
 
 
 
 
 
 
 
 
2042
 
2043
  async def handle_contact_request(from_number: str):
2044
  """Handle contact request"""
 
3688
  return {"error": str(e)}
3689
 
3690
  async def handle_intelligent_product_inquiry(from_number: str, query: str, user_context: dict, reply_language: str = 'en'):
3691
+ """Handle product inquiry with OpenAI intelligence and media support, matching WhatsApp screenshot logic"""
3692
  try:
 
3693
  products = get_veterinary_product_matches(query)
 
3694
  if products:
 
3695
  if len(products) > 1:
3696
+ message = f"Certainly, here are the relevant products for your query:\n\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3697
  for i, product in enumerate(products, 1):
3698
+ product_name = product.get('Product Name', 'Unknown')
3699
+ category = product.get('Category', '')
3700
+ short_desc = product.get('Type', '') or product.get('Indications', '')
3701
+ message += f"{i}. {product_name}"
3702
+ if category:
3703
+ message += f" - {category}"
3704
+ if short_desc:
3705
+ message += f" / {short_desc}"
3706
+ message += "\n"
3707
+ message += (f"\nTo view detailed information about any product, reply with its number (1-{len(products)})\n"
3708
+ "Type 'main' to return to the main menu")
3709
+ send_whatsjet_message(from_number, message)
3710
+ if context_manager:
3711
+ context_manager.update_context(
3712
+ from_number,
3713
+ current_state='intelligent_products_menu',
3714
+ current_menu='intelligent_products_menu',
3715
+ current_menu_options=[str(i) for i in range(1, len(products)+1)],
3716
+ available_products=products
3717
+ )
3718
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3719
  else:
 
3720
  selected_product = products[0]
3721
+ if context_manager:
3722
+ context_manager.update_context(
3723
+ from_number,
3724
+ current_product=selected_product,
3725
+ current_state='product_inquiry',
3726
+ current_menu='product_inquiry',
3727
+ current_menu_options=list(MENU_CONFIG['product_inquiry']['option_descriptions'].values())
3728
+ )
3729
+ # The actual sending of product details should be handled by the caller
3730
+ return selected_product
 
 
 
 
3731
  else:
3732
+ send_whatsjet_message(from_number, " No products found matching your query.\nType 'main' to return to the main menu.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3733
  except Exception as e:
3734
+ logger.error(f"Error in handle_intelligent_product_inquiry: {e}")
3735
+ send_whatsjet_message(from_number, "❌ Error processing your request. Type 'main' to return to the main menu.")
 
 
 
3736
 
3737
  async def handle_contact_request(from_number: str):
3738
  """Handle contact request"""
 
3766
  current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
3767
  )
3768
 
3769
+ # Helper for restoring English terms in translations
3770
  def restore_english_terms(translated_text, original_text, product_names, category_names):
 
 
 
3771
  for name in product_names + category_names:
3772
  if name and name.lower() in translated_text.lower() and name.lower() not in original_text.lower():
 
3773
  continue
 
 
3774
  translated_text = translated_text.replace(name, name)
3775
  return translated_text
3776