DreamStream-1 commited on
Commit
bb78ebd
·
verified ·
1 Parent(s): be3efeb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +349 -9
app.py CHANGED
@@ -2687,6 +2687,9 @@ async def handle_ai_chat_mode(from_number: str, query: str, reply_language: str
2687
  try:
2688
  logger.info(f"[AI Chat] Processing query: '{query}' for {from_number} in {reply_language}")
2689
 
 
 
 
2690
  # Check for navigation commands first
2691
  if query.lower().strip() in ['main', 'menu', 'start', 'home', 'back']:
2692
  logger.info(f"[AI Chat] Navigation command detected: '{query}' -> returning to main menu")
@@ -2723,13 +2726,15 @@ async def handle_ai_chat_mode(from_number: str, query: str, reply_language: str
2723
 
2724
  # Get all products data for context
2725
  all_products = []
 
2726
  if products_df is not None and not products_df.empty:
2727
  all_products = products_df.to_dict('records')
 
2728
 
2729
  # Create comprehensive context for AI
2730
  products_context = ""
2731
  if all_products:
2732
- products_context = "Available Veterinary Products:\n"
2733
  for i, product in enumerate(all_products[:50], 1): # Limit to first 50 products for context
2734
  product_name = product.get('Product Name', 'N/A')
2735
  category = product.get('Category', 'N/A')
@@ -2739,13 +2744,15 @@ async def handle_ai_chat_mode(from_number: str, query: str, reply_language: str
2739
  products_context += f" Composition: {composition}\n"
2740
  products_context += f" Target Species: {target_species}\n\n"
2741
 
2742
- # Create AI prompt
2743
  if reply_language == 'ur':
2744
  prompt = f"""
2745
  آپ Apex Biotical کے Veterinary AI Assistant ہیں۔ آپ کو veterinary products اور treatments کے بارے میں معلومات فراہم کرنی ہیں۔
2746
 
2747
  یوزر کا سوال: {query}
2748
 
 
 
2749
  دستیاب veterinary products:
2750
  {products_context}
2751
 
@@ -2755,6 +2762,7 @@ async def handle_ai_chat_mode(from_number: str, query: str, reply_language: str
2755
  3. اگر یہ general veterinary advice ہے تو professional guidance دیں
2756
  4. اردو میں جواب دیں
2757
  5. جواب professional اور helpful ہو
 
2758
 
2759
  جواب:
2760
  """
@@ -2764,6 +2772,8 @@ You are Apex Biotical's Veterinary AI Assistant. You provide information about v
2764
 
2765
  User Query: {query}
2766
 
 
 
2767
  Available Veterinary Products:
2768
  {products_context}
2769
 
@@ -2773,6 +2783,7 @@ Please:
2773
  3. If it's general veterinary advice, provide professional guidance
2774
  4. Answer in English
2775
  5. Keep the response professional and helpful
 
2776
 
2777
  Response:
2778
  """
@@ -2819,16 +2830,20 @@ Response:
2819
  error_msg = "❌ AI Assistant encountered an error. Please try again or type 'main' to return to main menu."
2820
  send_whatsjet_message(from_number, error_msg)
2821
 
2822
- def generate_veterinary_welcome_message(phone_number, user_context):
2823
- return (
2824
- "👋 Welcome to Apex Biotical Veterinary WhatsApp Bot!\n"
2825
- "How can I assist you today?\n"
2826
- "1️⃣ Search Products\n"
 
 
2827
  "2️⃣ Browse Categories\n"
2828
  "3️⃣ Download Catalog\n"
2829
- "4️⃣ Chat with Veterinary AI Assistant\n"
2830
- "Please reply with a number (1-4) or type your question."
 
2831
  )
 
2832
 
2833
  @app.get("/test-whatsjet")
2834
  async def test_whatsjet():
@@ -2839,6 +2854,331 @@ async def test_whatsjet():
2839
  except Exception as e:
2840
  return {"error": str(e)}
2841
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2842
  if __name__ == "__main__":
2843
  # Launch FastAPI app
2844
  import uvicorn
 
2687
  try:
2688
  logger.info(f"[AI Chat] Processing query: '{query}' for {from_number} in {reply_language}")
2689
 
2690
+ # Get user context
2691
+ user_context = context_manager.get_context(from_number)
2692
+
2693
  # Check for navigation commands first
2694
  if query.lower().strip() in ['main', 'menu', 'start', 'home', 'back']:
2695
  logger.info(f"[AI Chat] Navigation command detected: '{query}' -> returning to main menu")
 
2726
 
2727
  # Get all products data for context
2728
  all_products = []
2729
+ total_products = 0
2730
  if products_df is not None and not products_df.empty:
2731
  all_products = products_df.to_dict('records')
2732
+ total_products = len(products_df)
2733
 
2734
  # Create comprehensive context for AI
2735
  products_context = ""
2736
  if all_products:
2737
+ products_context = f"Available Veterinary Products (Total: {total_products} products):\n"
2738
  for i, product in enumerate(all_products[:50], 1): # Limit to first 50 products for context
2739
  product_name = product.get('Product Name', 'N/A')
2740
  category = product.get('Category', 'N/A')
 
2744
  products_context += f" Composition: {composition}\n"
2745
  products_context += f" Target Species: {target_species}\n\n"
2746
 
2747
+ # Create AI prompt with accurate product count
2748
  if reply_language == 'ur':
2749
  prompt = f"""
2750
  آپ Apex Biotical کے Veterinary AI Assistant ہیں۔ آپ کو veterinary products اور treatments کے بارے میں معلومات فراہم کرنی ہیں۔
2751
 
2752
  یوزر کا سوال: {query}
2753
 
2754
+ کل veterinary products کی تعداد: {total_products}
2755
+
2756
  دستیاب veterinary products:
2757
  {products_context}
2758
 
 
2762
  3. اگر یہ general veterinary advice ہے تو professional guidance دیں
2763
  4. اردو میں جواب دیں
2764
  5. جواب professional اور helpful ہو
2765
+ 6. اگر یوزر نے products کی تعداد کے بارے میں پوچھا ہے تو صحیح تعداد ({total_products}) بتائیں
2766
 
2767
  جواب:
2768
  """
 
2772
 
2773
  User Query: {query}
2774
 
2775
+ Total number of veterinary products: {total_products}
2776
+
2777
  Available Veterinary Products:
2778
  {products_context}
2779
 
 
2783
  3. If it's general veterinary advice, provide professional guidance
2784
  4. Answer in English
2785
  5. Keep the response professional and helpful
2786
+ 6. If the user asks about the number of products, provide the accurate count ({total_products})
2787
 
2788
  Response:
2789
  """
 
2830
  error_msg = "❌ AI Assistant encountered an error. Please try again or type 'main' to return to main menu."
2831
  send_whatsjet_message(from_number, error_msg)
2832
 
2833
+ def generate_veterinary_welcome_message(phone_number=None, user_context=None):
2834
+ """Generate enhanced welcome message with veterinary domain expertise"""
2835
+ welcome_msg = (
2836
+ "🏥 *Welcome to Apex Biotical Veterinary Bot*\n\n"
2837
+ "We provide comprehensive veterinary products and support.\n\n"
2838
+ "📋 *Available Options:*\n"
2839
+ "1️⃣ Search Veterinary Products\n"
2840
  "2️⃣ Browse Categories\n"
2841
  "3️⃣ Download Catalog\n"
2842
+ "4️⃣ Chat with Veterinary AI Assistant\n\n"
2843
+ "💬 *Select an option or ask about specific products*\n"
2844
+ "🎤 *You can also send voice messages*"
2845
  )
2846
+ return welcome_msg
2847
 
2848
  @app.get("/test-whatsjet")
2849
  async def test_whatsjet():
 
2854
  except Exception as e:
2855
  return {"error": str(e)}
2856
 
2857
+ # Load products data on startup
2858
+ def load_products_data():
2859
+ """Load products data from CSV file"""
2860
+ global products_df
2861
+ try:
2862
+ if os.path.exists(CSV_FILE):
2863
+ products_df = pd.read_csv(CSV_FILE)
2864
+ logger.info(f"✅ Loaded {len(products_df)} products from {CSV_FILE}")
2865
+ else:
2866
+ logger.warning(f"⚠️ CSV file {CSV_FILE} not found")
2867
+ products_df = pd.DataFrame()
2868
+ except Exception as e:
2869
+ logger.error(f"❌ Error loading products data: {e}")
2870
+ products_df = pd.DataFrame()
2871
+
2872
+ def convert_drive_link(link: str) -> str:
2873
+ """Convert Google Drive link to direct download link"""
2874
+ if 'drive.google.com' in link:
2875
+ file_id = link.split('/')[-2] if '/d/' in link else link.split('/')[-1]
2876
+ return f"https://drive.google.com/uc?export=download&id={file_id}"
2877
+ return link
2878
+
2879
+ def format_number_with_emoji(number: int) -> str:
2880
+ """Format number with emoji"""
2881
+ emoji_map = {
2882
+ 1: "1️⃣", 2: "2️⃣", 3: "3️⃣", 4: "4️⃣", 5: "5️⃣",
2883
+ 6: "6️⃣", 7: "7️⃣", 8: "8️⃣", 9: "9️⃣", 10: "🔟",
2884
+ 11: "1️⃣1️⃣", 12: "1️⃣2️⃣", 13: "1️⃣3️⃣", 14: "1️⃣4️⃣", 15: "1️⃣5️⃣",
2885
+ 16: "1️⃣6️⃣", 17: "1️⃣7️⃣", 18: "1️⃣8️⃣", 19: "1️⃣9️⃣", 20: "2️⃣0️⃣",
2886
+ 21: "2️⃣1️⃣", 22: "2️⃣2️⃣", 23: "2️⃣3️⃣"
2887
+ }
2888
+ return emoji_map.get(number, f"{number}.")
2889
+
2890
+ async def display_all_products(from_number: str):
2891
+ """Display all products in multiple messages and update menu context"""
2892
+ try:
2893
+ user_context = context_manager.get_context(from_number)
2894
+ current_state = user_context.get('current_state', 'main_menu')
2895
+ logger.info(f"[Display] display_all_products called for {from_number} in state: {current_state}")
2896
+ if current_state == 'all_products_menu':
2897
+ logger.warning(f"[Display] Already in all_products_menu state for {from_number}, skipping display")
2898
+ return
2899
+ if products_df is None or products_df.empty:
2900
+ send_whatsjet_message(from_number, "❌ No products available at the moment.")
2901
+ return
2902
+ # Set state to all_products_menu and store menu context
2903
+ products = products_df.to_dict('records')
2904
+ context_manager.update_context(
2905
+ from_number,
2906
+ current_state='all_products_menu',
2907
+ current_menu='all_products_menu',
2908
+ current_menu_options=[p.get('Product Name', 'Unknown') for p in products],
2909
+ available_products=products
2910
+ )
2911
+ logger.info(f"[Display] Set state to all_products_menu for {from_number}")
2912
+ # Send products in chunks
2913
+ chunk_size = 5
2914
+ for i in range(0, len(products), chunk_size):
2915
+ chunk = products[i:i + chunk_size]
2916
+ message = f"📋 *Products ({i+1}-{min(i+chunk_size, len(products))} of {len(products)})*\n\n"
2917
+ for j, product in enumerate(chunk, i+1):
2918
+ message += f"{format_number_with_emoji(j)} {product.get('Product Name', 'Unknown')}\n"
2919
+ if product.get('Category'):
2920
+ message += f" Category: {product.get('Category')}\n"
2921
+ message += "\n"
2922
+ send_whatsjet_message(from_number, message)
2923
+ send_whatsjet_message(from_number,
2924
+ "💬 Type a product name to get detailed information, or type 'main' to return to main menu.")
2925
+ except Exception as e:
2926
+ logger.error(f"[Display] Error displaying products: {e}")
2927
+ send_whatsjet_message(from_number, "❌ Error displaying products. Please try again.")
2928
+
2929
+ def get_all_categories():
2930
+ """Return a list of all unique categories from the products DataFrame"""
2931
+ if products_df is not None and not products_df.empty:
2932
+ return list(products_df['Category'].unique())
2933
+ return []
2934
+
2935
+ def get_products_by_category(category: str):
2936
+ """Get products by category"""
2937
+ if products_df is None or products_df.empty:
2938
+ return []
2939
+ category_products = products_df[products_df['Category'] == category]
2940
+ return category_products.to_dict('records')
2941
+
2942
+ # Enhanced product follow-up handling
2943
+ async def handle_veterinary_product_followup(selection: str, from_number: str) -> None:
2944
+ """
2945
+ Handle product follow-up selections with enhanced veterinary domain support
2946
+ """
2947
+ try:
2948
+ user_context = context_manager.get_context(from_number)
2949
+ current_product = user_context.get('current_product')
2950
+
2951
+ if selection == '1':
2952
+ # Talk to Veterinary Consultant
2953
+ current_product = user_context.get('current_product')
2954
+ product_name = current_product.get('Product Name', 'the selected product') if current_product else 'the selected product'
2955
+ consultant_msg = (
2956
+ f"📞 Contact Veterinary Consultant\n\n"
2957
+ f"Product: {product_name}\n\n"
2958
+ "Please provide your details:\n"
2959
+ "* Name and location\n"
2960
+ "* Specific inquiry\n\n"
2961
+ "💬 Example: Dr. Ali - Multan - Need consultation for respiratory problems\n\n"
2962
+ "Type main at any time to go to main menu."
2963
+ )
2964
+ send_whatsjet_message(from_number, consultant_msg)
2965
+ elif selection == '2':
2966
+ # Inquire about Product Availability
2967
+ await handle_availability_inquiry(from_number, user_context)
2968
+ elif selection == '3':
2969
+ # Back to Main Menu
2970
+ welcome_msg = generate_veterinary_welcome_message(from_number, user_context)
2971
+ send_whatsjet_message(from_number, welcome_msg)
2972
+ context_manager.update_context(
2973
+ from_number,
2974
+ current_state='main_menu',
2975
+ current_menu='main_menu',
2976
+ current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
2977
+ )
2978
+ return
2979
+ else:
2980
+ send_whatsjet_message(from_number, "❌ Invalid selection. Please choose 1, 2, or 3.")
2981
+ return
2982
+ except Exception as e:
2983
+ logger.error(f"Error in product follow-up: {e}")
2984
+ welcome_msg = generate_veterinary_welcome_message(from_number, user_context)
2985
+ send_whatsjet_message(from_number, welcome_msg)
2986
+ context_manager.update_context(
2987
+ from_number,
2988
+ current_state='main_menu',
2989
+ current_menu='main_menu',
2990
+ current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
2991
+ )
2992
+
2993
+ # Enhanced product inquiry handling
2994
+ async def handle_veterinary_product_inquiry(product_name: str, from_number: str) -> None:
2995
+ """
2996
+ Handle product inquiry with enhanced veterinary domain support
2997
+ """
2998
+ try:
2999
+ # Search for the product
3000
+ products = get_veterinary_product_matches(product_name)
3001
+
3002
+ if products:
3003
+ selected_product = products[0]
3004
+ context_manager.update_context(
3005
+ from_number,
3006
+ current_product=selected_product,
3007
+ current_state='product_inquiry',
3008
+ current_menu='product_inquiry',
3009
+ current_menu_options=list(MENU_CONFIG['product_inquiry']['option_descriptions'].values())
3010
+ )
3011
+ # Get updated context with last message
3012
+ context = context_manager.get_context(from_number)
3013
+ response = generate_veterinary_product_response(selected_product, context)
3014
+ send_whatsjet_message(from_number, response)
3015
+
3016
+ # Add to conversation history
3017
+ context_manager.add_to_history(from_number, product_name, response)
3018
+
3019
+ else:
3020
+ # Enhanced "not found" response with veterinary suggestions
3021
+ message = (
3022
+ "❌ *Product Not Found*\n\n"
3023
+ f"🔍 *We couldn't find '{product_name}' in our veterinary database.*\n\n"
3024
+ "💡 *Try these alternatives:*\n"
3025
+ "• Check spelling (e.g., 'Hydropex' not 'Hydro pex')\n"
3026
+ "• Search by symptoms (e.g., 'respiratory', 'liver support')\n"
3027
+ "• Search by category (e.g., 'antibiotic', 'vitamin')\n"
3028
+ "• Search by species (e.g., 'poultry', 'livestock')\n\n"
3029
+ "🏥 *Popular Veterinary Products:*\n"
3030
+ "• Hydropex (Electrolyte supplement)\n"
3031
+ "• Heposel (Liver tonic)\n"
3032
+ "• Bromacid (Respiratory support)\n"
3033
+ "• Tribiotic (Antibiotic)\n"
3034
+ "• Symodex (Multivitamin)\n\n"
3035
+ "💬 *Type 'main' to return to main menu or try another search.*"
3036
+ )
3037
+
3038
+ send_whatsjet_message(from_number, message)
3039
+
3040
+ except Exception as e:
3041
+ logger.error(f"Error in product inquiry: {e}")
3042
+ # Instead of sending a generic error, return to main menu
3043
+ welcome_msg = generate_veterinary_welcome_message(from_number, user_context)
3044
+ send_whatsjet_message(from_number, welcome_msg)
3045
+ 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()))
3046
+
3047
+ async def handle_category_selection(selection: str, from_number: str):
3048
+ """Handle category selection from category_selection_menu state"""
3049
+ try:
3050
+ user_context = context_manager.get_context(from_number)
3051
+ available_categories = user_context.get('available_categories', [])
3052
+
3053
+ logger.info(f"[Category] Handling selection '{selection}' for {from_number}")
3054
+ logger.info(f"[Category] Available categories: {len(available_categories)}")
3055
+
3056
+ if not available_categories:
3057
+ logger.warning("[Category] No available categories")
3058
+ send_whatsjet_message(from_number, "❌ No categories available. Please type 'main' to return to main menu.")
3059
+ return
3060
+
3061
+ if selection.isdigit() and 1 <= int(selection) <= len(available_categories):
3062
+ selected_category = available_categories[int(selection) - 1]
3063
+ logger.info(f"[Category] Selected category: '{selected_category}'")
3064
+
3065
+ products = get_products_by_category(selected_category)
3066
+ logger.info(f"[Category] Found {len(products)} products in category '{selected_category}'")
3067
+
3068
+ if products:
3069
+ product_message = f"📦 *Products in {selected_category}*\n\n"
3070
+ for i, product in enumerate(products[:10], 1): # Show first 10 products
3071
+ product_message += f"{format_number_with_emoji(i)} {product.get('Product Name', 'Unknown')}\n"
3072
+
3073
+ if len(products) > 10:
3074
+ product_message += f"\n... and {len(products) - 10} more products"
3075
+
3076
+ product_message += "\n\nSelect a product number or type 'main' to return to main menu."
3077
+
3078
+ logger.info(f"[Category] Sending product message for category '{selected_category}'")
3079
+ send_whatsjet_message(from_number, product_message)
3080
+ context_manager.update_context(
3081
+ from_number,
3082
+ current_state='category_products_menu',
3083
+ current_menu='category_products_menu',
3084
+ current_menu_options=[f"Product {i+1}" for i in range(len(products))],
3085
+ available_products=products,
3086
+ current_category=selected_category
3087
+ )
3088
+ logger.info(f"[Category] Updated context to category_products_menu with {len(products)} products")
3089
+ else:
3090
+ logger.warning(f"[Category] No products found in category '{selected_category}'")
3091
+ send_whatsjet_message(from_number, f"❌ No products found in {selected_category}")
3092
+ else:
3093
+ logger.warning(f"[Category] Invalid category selection: '{selection}' (valid range: 1-{len(available_categories)})")
3094
+ send_whatsjet_message(from_number, "❌ Invalid selection. Please choose a valid category number.")
3095
+
3096
+ except Exception as e:
3097
+ logger.error(f"[Category] Error handling category selection: {e}")
3098
+ # Instead of sending a generic error, return to main menu
3099
+ welcome_msg = generate_veterinary_welcome_message(from_number, user_context)
3100
+ send_whatsjet_message(from_number, welcome_msg)
3101
+ context_manager.update_context(
3102
+ from_number,
3103
+ current_state='main_menu',
3104
+ current_menu='main_menu',
3105
+ current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
3106
+ )
3107
+
3108
+ def get_menu_validation_message(current_state: str, user_context: dict) -> str:
3109
+ """Get specific validation message for the current menu state"""
3110
+ if current_state == 'main_menu':
3111
+ return "❌ Invalid selection for Main Menu. Please choose:\n1️⃣ Search Veterinary Products\n2️⃣ Browse Categories\n3️⃣ Download Catalog\n4️⃣ Chat with Veterinary AI Assistant\n\n💬 Type 'main' to return to main menu."
3112
+
3113
+ elif current_state == 'all_products_menu':
3114
+ available_products = user_context.get('available_products', [])
3115
+ total_products = len(available_products) if available_products else 23
3116
+ return f"❌ Invalid selection for Product List. Please choose a number between 1 and {total_products}.\n\n💬 Type 'main' to return to main menu."
3117
+
3118
+ elif current_state == 'category_selection_menu':
3119
+ available_categories = user_context.get('available_categories', [])
3120
+ total_categories = len(available_categories) if available_categories else 0
3121
+ if total_categories > 0:
3122
+ return f"❌ Invalid selection for Category List. Please choose a number between 1 and {total_categories}.\n\n💬 Type 'main' to return to main menu."
3123
+ else:
3124
+ return "❌ No categories available. Please type 'main' to return to main menu."
3125
+
3126
+ elif current_state == 'category_products_menu':
3127
+ available_products = user_context.get('available_products', [])
3128
+ total_products = len(available_products) if available_products else 0
3129
+ if total_products > 0:
3130
+ return f"❌ Invalid selection for Category Products. Please choose a number between 1 and {total_products}.\n\n💬 Type 'main' to return to main menu."
3131
+ else:
3132
+ return "❌ No products available in this category. Please type 'main' to return to main menu."
3133
+
3134
+ elif current_state == 'product_inquiry':
3135
+ return "❌ Invalid selection for Product Options. Please choose:\n1️⃣ Talk to Veterinary Consultant\n2️⃣ Inquire about Product Availability\n3️⃣ Back to Main Menu"
3136
+
3137
+ elif current_state == 'ai_chat_mode':
3138
+ return "💬 *You're in AI Chat mode. Ask me anything about veterinary care!*\n\nType 'main' to return to main menu."
3139
+
3140
+ else:
3141
+ return "❌ Invalid selection. Please type 'main' to return to main menu."
3142
+
3143
+ def is_valid_menu_selection(selection: str, current_state: str, user_context: dict) -> bool:
3144
+ """Check if a selection is valid for the current menu state"""
3145
+ # Use the intelligent voice command processor for consistent handling
3146
+ mapped_selection = process_intelligent_voice_command(selection, current_state, user_context)
3147
+
3148
+ if not mapped_selection.isdigit():
3149
+ return False
3150
+
3151
+ selection_num = int(mapped_selection)
3152
+
3153
+ if current_state == 'main_menu':
3154
+ return 1 <= selection_num <= 4
3155
+
3156
+ elif current_state == 'all_products_menu':
3157
+ available_products = user_context.get('available_products', [])
3158
+ total_products = len(available_products) if available_products else 23
3159
+ return 1 <= selection_num <= total_products
3160
+
3161
+ elif current_state == 'category_selection_menu':
3162
+ available_categories = user_context.get('available_categories', [])
3163
+ total_categories = len(available_categories) if available_categories else 0
3164
+ return 1 <= selection_num <= total_categories
3165
+
3166
+ elif current_state == 'category_products_menu':
3167
+ available_products = user_context.get('available_products', [])
3168
+ total_products = len(available_products) if available_products else 0
3169
+ return 1 <= selection_num <= total_products
3170
+
3171
+ elif current_state == 'product_inquiry':
3172
+ return 1 <= selection_num <= 3
3173
+
3174
+ elif current_state == 'ai_chat_mode':
3175
+ return mapped_selection == 'main'
3176
+
3177
+ return False
3178
+
3179
+ # Load products on startup
3180
+ load_products_data()
3181
+
3182
  if __name__ == "__main__":
3183
  # Launch FastAPI app
3184
  import uvicorn