Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -3816,9 +3816,13 @@ async def display_all_products(from_number: str):
|
|
3816 |
user_context = context_manager.get_context(from_number)
|
3817 |
current_state = user_context.get('current_state', 'main_menu')
|
3818 |
logger.info(f"[Display] display_all_products called for {from_number} in state: {current_state}")
|
|
|
|
|
|
|
3819 |
if products_df is None or products_df.empty:
|
3820 |
send_whatsjet_message(from_number, "β No products available at the moment.")
|
3821 |
return
|
|
|
3822 |
products = products_df.to_dict('records')
|
3823 |
context_manager.update_context(
|
3824 |
from_number,
|
@@ -3828,6 +3832,7 @@ async def display_all_products(from_number: str):
|
|
3828 |
available_products=products
|
3829 |
)
|
3830 |
logger.info(f"[Display] Set state to all_products_menu for {from_number}")
|
|
|
3831 |
chunk_size = 5
|
3832 |
for i in range(0, len(products), chunk_size):
|
3833 |
chunk = products[i:i + chunk_size]
|
@@ -3839,7 +3844,7 @@ async def display_all_products(from_number: str):
|
|
3839 |
message += "\n"
|
3840 |
send_whatsjet_message(from_number, message)
|
3841 |
send_whatsjet_message(from_number,
|
3842 |
-
"π¬ Type a product
|
3843 |
except Exception as e:
|
3844 |
logger.error(f"[Display] Error displaying products: {e}")
|
3845 |
send_whatsjet_message(from_number, "β Error displaying products. Please try again.")
|
@@ -3897,111 +3902,80 @@ async def handle_category_selection(selection: str, from_number: str):
|
|
3897 |
send_helpful_guidance(from_number, 'category_selection_menu')
|
3898 |
|
3899 |
def get_menu_validation_message(current_state: str, user_context: dict) -> str:
|
3900 |
-
"""Get
|
3901 |
if current_state == 'main_menu':
|
3902 |
return (
|
3903 |
-
"
|
3904 |
-
"Please
|
3905 |
-
"π *Available Options:*\n"
|
3906 |
"1οΈβ£ Search Veterinary Products\n"
|
3907 |
"2οΈβ£ Browse Categories\n"
|
3908 |
"3οΈβ£ Download Catalog\n"
|
3909 |
"4οΈβ£ Chat with Veterinary AI Assistant\n\n"
|
3910 |
-
"
|
3911 |
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')\n"
|
3912 |
-
"β’ Type 'main' to refresh the menu
|
3913 |
-
"β’ Ask about symptoms or categories"
|
3914 |
)
|
3915 |
elif current_state == 'all_products_menu':
|
3916 |
if products_df is not None and not products_df.empty:
|
3917 |
total_products = len(products_df)
|
3918 |
return (
|
3919 |
-
f"
|
3920 |
f"Please choose a product number between 1 and {total_products}.\n\n"
|
3921 |
-
"
|
3922 |
-
"β’ Type a
|
3923 |
-
"β’ Type 'main' to return to main menu
|
3924 |
-
"β’ Ask about product categories"
|
3925 |
)
|
3926 |
else:
|
3927 |
-
return
|
3928 |
-
"β οΈ *No Products Available*\n\n"
|
3929 |
-
"Currently no products are loaded in the system.\n\n"
|
3930 |
-
"π‘ *Please:*\n"
|
3931 |
-
"β’ Type 'main' to return to main menu\n"
|
3932 |
-
"β’ Contact support if this issue persists"
|
3933 |
-
)
|
3934 |
elif current_state == 'category_products_menu':
|
3935 |
available_products = user_context.get('available_products', [])
|
3936 |
if available_products:
|
3937 |
return (
|
3938 |
-
f"
|
3939 |
f"Please choose a product number between 1 and {len(available_products)}.\n\n"
|
3940 |
-
"
|
3941 |
-
"β’ Type a
|
3942 |
-
"β’ Type 'main' to return to main menu
|
3943 |
-
"β’ Browse other categories"
|
3944 |
)
|
3945 |
else:
|
3946 |
-
return
|
3947 |
-
"β οΈ *No Products in Category*\n\n"
|
3948 |
-
"This category currently has no available products.\n\n"
|
3949 |
-
"π‘ *Please:*\n"
|
3950 |
-
"β’ Type 'main' to return to main menu\n"
|
3951 |
-
"β’ Browse other categories\n"
|
3952 |
-
"β’ Ask about specific products"
|
3953 |
-
)
|
3954 |
elif current_state == 'category_selection_menu':
|
3955 |
available_categories = user_context.get('available_categories', [])
|
3956 |
if available_categories:
|
3957 |
return (
|
3958 |
-
f"
|
3959 |
f"Please choose a category number between 1 and {len(available_categories)}.\n\n"
|
3960 |
-
"
|
3961 |
-
"β’ Type a
|
3962 |
-
"β’ Type 'main' to return to main menu
|
3963 |
-
"β’ Ask about product types"
|
3964 |
)
|
3965 |
else:
|
3966 |
-
return
|
3967 |
-
"β οΈ *No Categories Available*\n\n"
|
3968 |
-
"Currently no product categories are available.\n\n"
|
3969 |
-
"π‘ *Please:*\n"
|
3970 |
-
"β’ Type 'main' to return to main menu\n"
|
3971 |
-
"β’ Ask about specific products\n"
|
3972 |
-
"β’ Contact support if needed"
|
3973 |
-
)
|
3974 |
elif current_state == 'product_inquiry':
|
3975 |
return (
|
3976 |
-
"
|
3977 |
-
"Please choose
|
3978 |
-
"π *Available Actions:*\n"
|
3979 |
"1οΈβ£ Talk to Veterinary Consultant\n"
|
3980 |
"2οΈβ£ Inquire About Availability\n"
|
3981 |
"3οΈβ£ Back to Main Menu\n\n"
|
3982 |
-
"
|
3983 |
-
"β’ Type
|
3984 |
-
"β’ Type 'main' to return to main menu
|
3985 |
-
"β’ Ask about related products"
|
3986 |
)
|
3987 |
elif current_state == 'intelligent_products_menu':
|
3988 |
-
available_products = user_context.get('available_products', [])
|
3989 |
return (
|
3990 |
-
|
3991 |
-
|
3992 |
-
"
|
3993 |
-
"β’ Type a
|
3994 |
-
"β’ Type 'main' to return to main menu
|
3995 |
-
"β’ Ask about different categories"
|
3996 |
)
|
3997 |
else:
|
3998 |
return (
|
3999 |
-
"
|
4000 |
"Please choose a valid option or type 'main' to return to main menu.\n\n"
|
4001 |
-
"
|
4002 |
-
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')
|
4003 |
-
"β’ Type 'main' to return to main menu\n"
|
4004 |
-
"β’ Ask about veterinary products or categories"
|
4005 |
)
|
4006 |
|
4007 |
def is_valid_menu_selection(selection: str, current_state: str, user_context: dict) -> bool:
|
@@ -4009,39 +3983,6 @@ def is_valid_menu_selection(selection: str, current_state: str, user_context: di
|
|
4009 |
is_valid, _ = validate_menu_selection(selection, current_state, user_context)
|
4010 |
return is_valid
|
4011 |
|
4012 |
-
def get_irrelevant_query_response(query: str, current_state: str, reply_language: str = 'en') -> str:
|
4013 |
-
"""Get professional response for irrelevant or unclear queries"""
|
4014 |
-
if reply_language == 'ur':
|
4015 |
-
return (
|
4016 |
-
"π€ *Apex Biotical Veterinary Assistant*\n\n"
|
4017 |
-
"Ψ’ΩΎ Ϊ©Ψ§ Ψ³ΩΨ§Ω ΩΨ§ΨΆΨ ΩΫΫΪΊ ΫΫ ΫΨ§ ΫΫ ΩΫΩΉΨ±ΩΨ±Ϋ Ω
Ψ΅ΩΩΨΉΨ§Ψͺ Ψ³Ϋ Ω
ΨͺΨΉΩΩ ΩΫΫΪΊ ΫΫΫ\n\n"
|
4018 |
-
"π‘ *Ω
ΫΪΊ Ψ’ΩΎ Ϊ©Ϋ Ω
Ψ―Ψ― Ϊ©Ψ± Ψ³Ϊ©ΨͺΨ§ ΫΩΪΊ:*\n"
|
4019 |
-
"β’ ΩΫΩΉΨ±ΩΨ±Ϋ Ω
Ψ΅ΩΩΨΉΨ§Ψͺ Ϊ©Ϋ Ψ¨Ψ§Ψ±Ϋ Ω
ΫΪΊ Ω
ΨΉΩΩΩ
Ψ§Ψͺ\n"
|
4020 |
-
"β’ Ω
Ψ΅ΩΩΨΉΨ§Ψͺ Ϊ©Ϋ ΨͺΩΨ§Ψ΄ Ψ§ΩΨ± Ψ¨Ψ±Ψ§Ψ€Ψ²\n"
|
4021 |
-
"β’ ΩΫΩΉΨ±ΩΨ±Ϋ Ω
Ψ΄ΩΨ±Ϋ Ψ§ΩΨ± Ψ±ΫΩΩ
Ψ§Ψ¦Ϋ\n"
|
4022 |
-
"β’ Ω
Ψ΅ΩΩΨΉΨ§Ψͺ Ϊ©Ϋ Ψ―Ψ³ΨͺΫΨ§Ψ¨Ϋ Ϊ©Ϋ Ψ¨Ψ§Ψ±Ϋ Ω
ΫΪΊ ΩΎΩΪΪΎΩΨ§\n\n"
|
4023 |
-
"π *Ω
Ψ«Ψ§Ω Ϊ©Ϋ Ψ·ΩΨ± ΩΎΨ±:*\n"
|
4024 |
-
"β’ 'hydropex Ϊ©Ϋ Ψ¨Ψ§Ψ±Ϋ Ω
ΫΪΊ Ψ¨ΨͺΨ§Ψ¦ΫΪΊ'\n"
|
4025 |
-
"β’ 'Ψ³Ψ§ΩΨ³ Ϊ©Ϋ Ω
Ψ΅ΩΩΨΉΨ§Ψͺ Ϊ©ΩΩ Ψ³Ϋ ΫΫΪΊΨ'\n"
|
4026 |
-
"β’ 'main' ΩΪ©ΪΎ Ϊ©Ψ± Ω
ΫΩ Ω
ΫΩΩ ΩΎΨ± Ψ¬Ψ§Ψ¦ΫΪΊ"
|
4027 |
-
)
|
4028 |
-
else:
|
4029 |
-
return (
|
4030 |
-
"π€ *Apex Biotical Veterinary Assistant*\n\n"
|
4031 |
-
"I'm here to help you with veterinary products and information. "
|
4032 |
-
"Your query doesn't seem to be related to our veterinary services.\n\n"
|
4033 |
-
"π‘ *I can help you with:*\n"
|
4034 |
-
"β’ Information about veterinary products\n"
|
4035 |
-
"β’ Product search and browsing\n"
|
4036 |
-
"β’ Veterinary advice and guidance\n"
|
4037 |
-
"β’ Product availability inquiries\n\n"
|
4038 |
-
"π *Examples of what you can ask:*\n"
|
4039 |
-
"β’ 'Tell me about hydropex'\n"
|
4040 |
-
"β’ 'What respiratory products do you have?'\n"
|
4041 |
-
"β’ 'Show me all antibiotics'\n"
|
4042 |
-
"β’ Type 'main' to return to main menu"
|
4043 |
-
)
|
4044 |
-
|
4045 |
def generate_veterinary_welcome_message(phone_number=None, user_context=None):
|
4046 |
"""Generate veterinary welcome message"""
|
4047 |
return (
|
@@ -4072,11 +4013,6 @@ async def handle_veterinary_product_followup(selection: str, from_number: str) -
|
|
4072 |
send_whatsjet_message(from_number, "β No product selected. Please search for a product first.")
|
4073 |
return
|
4074 |
|
4075 |
-
# Validate that the selection is a valid follow-up option (1, 2, or 3)
|
4076 |
-
if selection not in ['1', '2', '3']:
|
4077 |
-
send_whatsjet_message(from_number, "β Invalid selection. Please choose 1, 2, or 3.")
|
4078 |
-
return
|
4079 |
-
|
4080 |
if selection == '1':
|
4081 |
# Talk to Veterinary Consultant
|
4082 |
product_name = current_product.get('Product Name', 'the selected product')
|
@@ -4096,11 +4032,9 @@ async def handle_veterinary_product_followup(selection: str, from_number: str) -
|
|
4096 |
current_menu='contact_request',
|
4097 |
current_menu_options=['Provide contact details']
|
4098 |
)
|
4099 |
-
|
4100 |
elif selection == '2':
|
4101 |
# Inquire about Product Availability
|
4102 |
await handle_availability_inquiry(from_number, user_context)
|
4103 |
-
|
4104 |
elif selection == '3':
|
4105 |
welcome_msg = generate_veterinary_welcome_message(from_number, user_context)
|
4106 |
send_whatsjet_message(from_number, welcome_msg)
|
@@ -4111,6 +4045,9 @@ async def handle_veterinary_product_followup(selection: str, from_number: str) -
|
|
4111 |
current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
|
4112 |
)
|
4113 |
return
|
|
|
|
|
|
|
4114 |
except Exception as e:
|
4115 |
logger.error(f"Error in product follow-up: {e}")
|
4116 |
user_context = context_manager.get_context(from_number)
|
|
|
3816 |
user_context = context_manager.get_context(from_number)
|
3817 |
current_state = user_context.get('current_state', 'main_menu')
|
3818 |
logger.info(f"[Display] display_all_products called for {from_number} in state: {current_state}")
|
3819 |
+
if current_state == 'all_products_menu':
|
3820 |
+
logger.warning(f"[Display] Already in all_products_menu state for {from_number}, skipping display")
|
3821 |
+
return
|
3822 |
if products_df is None or products_df.empty:
|
3823 |
send_whatsjet_message(from_number, "β No products available at the moment.")
|
3824 |
return
|
3825 |
+
# Set state to all_products_menu and store menu context
|
3826 |
products = products_df.to_dict('records')
|
3827 |
context_manager.update_context(
|
3828 |
from_number,
|
|
|
3832 |
available_products=products
|
3833 |
)
|
3834 |
logger.info(f"[Display] Set state to all_products_menu for {from_number}")
|
3835 |
+
# Send products in chunks
|
3836 |
chunk_size = 5
|
3837 |
for i in range(0, len(products), chunk_size):
|
3838 |
chunk = products[i:i + chunk_size]
|
|
|
3844 |
message += "\n"
|
3845 |
send_whatsjet_message(from_number, message)
|
3846 |
send_whatsjet_message(from_number,
|
3847 |
+
"π¬ Type a product name to get detailed information, or type 'main' to return to main menu.")
|
3848 |
except Exception as e:
|
3849 |
logger.error(f"[Display] Error displaying products: {e}")
|
3850 |
send_whatsjet_message(from_number, "β Error displaying products. Please try again.")
|
|
|
3902 |
send_helpful_guidance(from_number, 'category_selection_menu')
|
3903 |
|
3904 |
def get_menu_validation_message(current_state: str, user_context: dict) -> str:
|
3905 |
+
"""Get appropriate validation message for current menu state"""
|
3906 |
if current_state == 'main_menu':
|
3907 |
return (
|
3908 |
+
"β *Invalid Selection*\n\n"
|
3909 |
+
"Please choose from the main menu:\n"
|
|
|
3910 |
"1οΈβ£ Search Veterinary Products\n"
|
3911 |
"2οΈβ£ Browse Categories\n"
|
3912 |
"3οΈβ£ Download Catalog\n"
|
3913 |
"4οΈβ£ Chat with Veterinary AI Assistant\n\n"
|
3914 |
+
"π¬ *You can also:*\n"
|
3915 |
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')\n"
|
3916 |
+
"β’ Type 'main' to refresh the menu"
|
|
|
3917 |
)
|
3918 |
elif current_state == 'all_products_menu':
|
3919 |
if products_df is not None and not products_df.empty:
|
3920 |
total_products = len(products_df)
|
3921 |
return (
|
3922 |
+
f"β *Invalid Product Selection*\n\n"
|
3923 |
f"Please choose a product number between 1 and {total_products}.\n\n"
|
3924 |
+
"π¬ *You can also:*\n"
|
3925 |
+
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')\n"
|
3926 |
+
"β’ Type 'main' to return to main menu"
|
|
|
3927 |
)
|
3928 |
else:
|
3929 |
+
return "β No products available. Type 'main' to return to main menu."
|
|
|
|
|
|
|
|
|
|
|
|
|
3930 |
elif current_state == 'category_products_menu':
|
3931 |
available_products = user_context.get('available_products', [])
|
3932 |
if available_products:
|
3933 |
return (
|
3934 |
+
f"β *Invalid Product Selection*\n\n"
|
3935 |
f"Please choose a product number between 1 and {len(available_products)}.\n\n"
|
3936 |
+
"π¬ *You can also:*\n"
|
3937 |
+
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')\n"
|
3938 |
+
"β’ Type 'main' to return to main menu"
|
|
|
3939 |
)
|
3940 |
else:
|
3941 |
+
return "β No products available in this category. Type 'main' to return to main menu."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3942 |
elif current_state == 'category_selection_menu':
|
3943 |
available_categories = user_context.get('available_categories', [])
|
3944 |
if available_categories:
|
3945 |
return (
|
3946 |
+
f"β *Invalid Category Selection*\n\n"
|
3947 |
f"Please choose a category number between 1 and {len(available_categories)}.\n\n"
|
3948 |
+
"π¬ *You can also:*\n"
|
3949 |
+
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')\n"
|
3950 |
+
"β’ Type 'main' to return to main menu"
|
|
|
3951 |
)
|
3952 |
else:
|
3953 |
+
return "β No categories available. Type 'main' to return to main menu."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3954 |
elif current_state == 'product_inquiry':
|
3955 |
return (
|
3956 |
+
"β *Invalid Selection*\n\n"
|
3957 |
+
"Please choose an option:\n"
|
|
|
3958 |
"1οΈβ£ Talk to Veterinary Consultant\n"
|
3959 |
"2οΈβ£ Inquire About Availability\n"
|
3960 |
"3οΈβ£ Back to Main Menu\n\n"
|
3961 |
+
"π¬ *You can also:*\n"
|
3962 |
+
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')\n"
|
3963 |
+
"β’ Type 'main' to return to main menu"
|
|
|
3964 |
)
|
3965 |
elif current_state == 'intelligent_products_menu':
|
|
|
3966 |
return (
|
3967 |
+
"β *Invalid Selection*\n\n"
|
3968 |
+
"Please choose a product number between 1 and {len(available_products)}.\n\n"
|
3969 |
+
"π¬ *You can also:*\n"
|
3970 |
+
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')\n"
|
3971 |
+
"β’ Type 'main' to return to main menu"
|
|
|
3972 |
)
|
3973 |
else:
|
3974 |
return (
|
3975 |
+
"β *Invalid Selection*\n\n"
|
3976 |
"Please choose a valid option or type 'main' to return to main menu.\n\n"
|
3977 |
+
"π¬ *You can also:*\n"
|
3978 |
+
"β’ Type a product name (e.g., 'hydropex', 'respira aid plus')"
|
|
|
|
|
3979 |
)
|
3980 |
|
3981 |
def is_valid_menu_selection(selection: str, current_state: str, user_context: dict) -> bool:
|
|
|
3983 |
is_valid, _ = validate_menu_selection(selection, current_state, user_context)
|
3984 |
return is_valid
|
3985 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3986 |
def generate_veterinary_welcome_message(phone_number=None, user_context=None):
|
3987 |
"""Generate veterinary welcome message"""
|
3988 |
return (
|
|
|
4013 |
send_whatsjet_message(from_number, "β No product selected. Please search for a product first.")
|
4014 |
return
|
4015 |
|
|
|
|
|
|
|
|
|
|
|
4016 |
if selection == '1':
|
4017 |
# Talk to Veterinary Consultant
|
4018 |
product_name = current_product.get('Product Name', 'the selected product')
|
|
|
4032 |
current_menu='contact_request',
|
4033 |
current_menu_options=['Provide contact details']
|
4034 |
)
|
|
|
4035 |
elif selection == '2':
|
4036 |
# Inquire about Product Availability
|
4037 |
await handle_availability_inquiry(from_number, user_context)
|
|
|
4038 |
elif selection == '3':
|
4039 |
welcome_msg = generate_veterinary_welcome_message(from_number, user_context)
|
4040 |
send_whatsjet_message(from_number, welcome_msg)
|
|
|
4045 |
current_menu_options=list(MENU_CONFIG['main_menu']['option_descriptions'].values())
|
4046 |
)
|
4047 |
return
|
4048 |
+
else:
|
4049 |
+
send_whatsjet_message(from_number, "β Invalid selection. Please choose 1, 2, or 3.")
|
4050 |
+
return
|
4051 |
except Exception as e:
|
4052 |
logger.error(f"Error in product follow-up: {e}")
|
4053 |
user_context = context_manager.get_context(from_number)
|