import data_manager import gemini_client import re import os def extract_order_id(query): """Attempts to extract an order ID (assumed to be a number) from the query.""" match = re.search(r'\b\d+\b', query) if match: return int(match.group(0)) return None def format_prompt(query, order_details=None, order_items=None, recent_orders=None): """Formats the prompt for the Gemini API, including context.""" prompt = f"You are an e-commerce customer support assistant. Answer the user's query based *only* on the provided information. If the information is insufficient, say so.\n\nUser Query: \"{query}\"\n\n" if order_details: prompt += "--- Order Information ---\n" prompt += f"Order ID: {order_details.get('order_id')}\n" prompt += f"Customer: {order_details.get('user_name')} ({order_details.get('email')})\n" prompt += f"Date: {order_details.get('order_date')}\n" prompt += f"Status: {order_details.get('status')}\n" prompt += f"Total: ${order_details.get('total_amount'):.2f}\n" if order_items: prompt += "\n--- Items in Order ---\n" for item in order_items: prompt += f"- {item.get('product_name')} (Qty: {item.get('quantity')}, Price/Unit: ${item.get('price_per_unit'):.2f})\n" if recent_orders: prompt += "\n--- Recent Orders ---\n" for order in recent_orders: prompt += f"- Order ID: {order.get('order_id')}, Date: {order.get('order_date')}, Status: {order.get('status')}, Total: ${order.get('total_amount'):.2f}\n" prompt += "\n---\nAssistant Response:" return prompt def main(): """Main loop for the chatbot interaction.""" print("Welcome to the E-commerce Chat Assistant!") print("You can ask about order status, items, or recent orders.") print("Example: 'What is the status of order 1?' or 'Show my recent orders for alice@example.com'") print("Type 'quit' to exit.") # Basic way to identify user - could be improved with login simulation user_email = input("Please enter your email address to start: ") user_info = data_manager.get_user_by_email(user_email) if not user_info: print(f"User with email {user_email} not found. Exiting.") return print(f"Welcome, {user_info['name']}!") user_id = user_info['user_id'] while True: query = input("\nYour query: ") if query.lower() == 'quit': break order_id = extract_order_id(query) order_details = None order_items = None recent_orders = None try: # Determine context based on query and extracted info if order_id: order_details = data_manager.get_order_details(order_id) if order_details: # Security check: Ensure the order belongs to the logged-in user if order_details['email'] != user_email: print(f"Order {order_id} does not belong to user {user_email}.") order_details = None # Clear details if not authorized else: # Fetch items only if order details are valid and authorized order_items = data_manager.get_order_items(order_id) else: print(f"Order ID {order_id} not found.") # Check for recent orders query (simple keyword check) elif "recent orders" in query.lower() or "my orders" in query.lower(): recent_orders = data_manager.get_user_recent_orders(user_id) if not recent_orders: print("You have no recent orders.") # Construct and send prompt if we have relevant context if order_details or recent_orders: prompt = format_prompt(query, order_details, order_items, recent_orders) print("\nAssistant thinking...") response = gemini_client.get_gemini_response(prompt) print(f"\nAssistant: {response}") elif order_id and not order_details: # Already handled the "not found" or "not authorized" message pass else: # If no specific context found, try sending the query directly (less reliable) # Or inform the user context is needed # print("Could not determine specific order information. Trying a general query...") # prompt = format_prompt(query) # Send without specific context # response = gemini_client.get_gemini_response(prompt) # print(f"\nAssistant: {response}") print("Please specify an order ID or ask about 'recent orders'.") except FileNotFoundError as e: print(f"Error: {e}. Please ensure the database exists.") break except Exception as e: print(f"An unexpected error occurred: {e}") print("Goodbye!") if __name__ == "__main__": # Optional: Run data generation if DB doesn't exist? # For simplicity, we assume generate_data.py is run manually first. if not os.path.exists(data_manager.DB_PATH): print(f"Database not found at {data_manager.DB_PATH}.") print("Please run 'python generate_data.py' first to create and populate the database.") else: main()