| """ |
| Nutricore Food Solution - Agent Tools (7 buyer-focused tools) |
| """ |
|
|
| import json |
| from agents import function_tool |
| from database import get_db, DELIVERY_INFO, RECIPES |
|
|
|
|
| |
|
|
| def _row_to_dict(row) -> dict: |
| return dict(row) if row else {} |
|
|
|
|
| def _get_product_by_id(product_id: int) -> dict: |
| conn = get_db() |
| cur = conn.cursor() |
| cur.execute("SELECT * FROM products WHERE id = %s", (product_id,)) |
| row = cur.fetchone() |
| cur.close() |
| conn.close() |
| return _row_to_dict(row) |
|
|
|
|
| |
|
|
| def browse_products_impl(category: str = "") -> dict: |
| conn = get_db() |
| cur = conn.cursor() |
| if category and category.lower() != "all": |
| cur.execute( |
| "SELECT id, name, category, weight, price, description, image FROM products WHERE LOWER(category) LIKE %s ORDER BY id", |
| (f"%{category.lower()}%",) |
| ) |
| else: |
| cur.execute( |
| "SELECT id, name, category, weight, price, description, image FROM products ORDER BY id" |
| ) |
| rows = cur.fetchall() |
| cur.close() |
| conn.close() |
|
|
| products = [dict(r) for r in rows] |
| categories = list({p["category"] for p in products}) |
| return { |
| "total": len(products), |
| "categories": sorted(categories), |
| "products": products |
| } |
|
|
|
|
| def get_product_info_impl(product_id: int) -> dict: |
| p = _get_product_by_id(product_id) |
| if not p: |
| return {"error": f"Product with id {product_id} not found"} |
| return p |
|
|
|
|
| def find_product_for_goal_impl(health_goal: str) -> dict: |
| GOAL_MAP = { |
| "weight_loss": "weight_loss", |
| "immunity": "immunity", |
| "energy": "energy", |
| "skin_health": "skin_health", |
| "digestion": "digestion", |
| "detox": "detox", |
| } |
| goal = GOAL_MAP.get(health_goal.lower().replace(" ", "_"), health_goal.lower()) |
|
|
| conn = get_db() |
| cur = conn.cursor() |
| cur.execute( |
| "SELECT id, name, category, weight, price, description, benefits FROM products WHERE health_goals LIKE %s", |
| (f"%{goal}%",) |
| ) |
| rows = cur.fetchall() |
| cur.close() |
| conn.close() |
|
|
| if not rows: |
| return {"error": f"No products found for goal: {health_goal}"} |
|
|
| products = [dict(r) for r in rows] |
|
|
| GOAL_DESCRIPTIONS = { |
| "weight_loss": "These products support weight loss through fiber, low calories, and metabolism boost.", |
| "immunity": "These products are rich in Vitamin C, antioxidants, and immune-boosting compounds.", |
| "energy": "These products provide natural energy through nutrients, iron, and carbohydrates.", |
| "skin_health": "These products contain antioxidants, Vitamin C, and nutrients for glowing skin.", |
| "digestion": "These products contain fiber, enzymes, and probiotics that support healthy digestion.", |
| "detox": "These products help cleanse the body and support liver and kidney function.", |
| } |
|
|
| return { |
| "health_goal": health_goal, |
| "explanation": GOAL_DESCRIPTIONS.get(goal, f"Products recommended for {health_goal}"), |
| "total": len(products), |
| "recommended_products": products |
| } |
|
|
|
|
| def get_recipe_ideas_impl(product_id: int = 0) -> dict: |
| if product_id and product_id > 0: |
| recipes = RECIPES.get(product_id, []) |
| product = _get_product_by_id(product_id) |
| if not product: |
| return {"error": f"Product {product_id} not found"} |
| if not recipes: |
| return { |
| "product": product.get("name"), |
| "message": f"Mix 1-2 tbsp of {product.get('name')} in smoothies, juices, or warm water.", |
| "recipes": [] |
| } |
| return { |
| "product": product.get("name"), |
| "recipes": recipes |
| } |
|
|
| |
| all_recipes = [] |
| for pid, recipe_list in RECIPES.items(): |
| p = _get_product_by_id(pid) |
| if p and recipe_list: |
| all_recipes.append({ |
| "product_id": pid, |
| "product_name": p.get("name"), |
| "recipe": recipe_list[0] |
| }) |
|
|
| return { |
| "message": "Here are some popular recipes using our powders:", |
| "recipes": all_recipes[:6] |
| } |
|
|
|
|
| def compare_products_impl(product_id_1: int, product_id_2: int) -> dict: |
| p1 = _get_product_by_id(product_id_1) |
| p2 = _get_product_by_id(product_id_2) |
|
|
| if not p1: |
| return {"error": f"Product {product_id_1} not found"} |
| if not p2: |
| return {"error": f"Product {product_id_2} not found"} |
|
|
| return { |
| "comparison": { |
| "product_1": { |
| "id": p1["id"], |
| "name": p1["name"], |
| "category": p1["category"], |
| "weight": p1["weight"], |
| "price": p1["price"], |
| "benefits": p1["benefits"], |
| "health_goals": p1["health_goals"], |
| "how_to_use": p1["how_to_use"], |
| }, |
| "product_2": { |
| "id": p2["id"], |
| "name": p2["name"], |
| "category": p2["category"], |
| "weight": p2["weight"], |
| "price": p2["price"], |
| "benefits": p2["benefits"], |
| "health_goals": p2["health_goals"], |
| "how_to_use": p2["how_to_use"], |
| } |
| }, |
| "price_difference": abs(p1["price"] - p2["price"]), |
| "cheaper": p1["name"] if p1["price"] < p2["price"] else p2["name"], |
| } |
|
|
|
|
| def check_price_and_delivery_impl(product_id: int, city: str = "") -> dict: |
| p = _get_product_by_id(product_id) |
| if not p: |
| return {"error": f"Product {product_id} not found"} |
|
|
| city_key = city.lower().strip() if city else "other" |
| delivery = DELIVERY_INFO.get(city_key, DELIVERY_INFO["other"]) |
|
|
| product_price = p["price"] |
| delivery_charge = delivery["charge"] |
| total = product_price + delivery_charge |
|
|
| return { |
| "product": {"id": p["id"], "name": p["name"], "weight": p["weight"], "price": product_price}, |
| "delivery": { |
| "city": delivery["city"], |
| "charge": delivery_charge, |
| "estimated_time": delivery["days"] |
| }, |
| "total_amount": total, |
| "note": "Free delivery on orders above PKR 3000" |
| } |
|
|
|
|
| def place_order_impl(name: str, phone: str, address: str, products: list) -> dict: |
| if not name or not phone or not address: |
| return {"error": "Please provide name, phone, and address to place order."} |
| if not products: |
| return {"error": "Please specify at least one product to order."} |
|
|
| total = 0 |
| order_items = [] |
| conn = get_db() |
|
|
| cur = conn.cursor() |
| for item in products: |
| product_id = item.get("product_id") or item.get("id") |
| qty = item.get("quantity", 1) |
| if product_id: |
| cur.execute("SELECT id, name, price FROM products WHERE id = %s", (product_id,)) |
| row = cur.fetchone() |
| if row: |
| p = dict(row) |
| subtotal = p["price"] * qty |
| total += subtotal |
| order_items.append({"product": p["name"], "qty": qty, "price": p["price"], "subtotal": subtotal}) |
|
|
| city = address.split(",")[-1].strip().lower() if "," in address else "other" |
| delivery = DELIVERY_INFO.get(city, DELIVERY_INFO["other"]) |
| total += delivery["charge"] |
|
|
| import json as _json |
| cur.execute( |
| "INSERT INTO orders (name, phone, address, city, products, total_amount) VALUES (%s, %s, %s, %s, %s, %s) RETURNING id", |
| (name, phone, address, city, _json.dumps(order_items), total) |
| ) |
| order_id = cur.fetchone()["id"] |
| cur.close() |
| conn.commit() |
| conn.close() |
|
|
| return { |
| "success": True, |
| "order_id": order_id, |
| "customer": name, |
| "items": order_items, |
| "delivery_charge": delivery["charge"], |
| "total_amount": total, |
| "estimated_delivery": delivery["days"], |
| "message": f"Order #{order_id} confirmed! Our team will contact you on {phone} via WhatsApp within 1 hour to confirm your order." |
| } |
|
|
|
|
| |
|
|
| @function_tool |
| def browse_products(category: str = "") -> str: |
| """Browse all products or filter by category. |
| |
| Args: |
| category: Optional category filter - 'Fruit Powders', 'Vegetable Powders', 'Green Leaf Powders', or empty for all |
| """ |
| result = browse_products_impl(category) |
| return str(result) |
|
|
|
|
| @function_tool |
| def get_product_info(product_id: int) -> str: |
| """Get full details about a specific product. |
| |
| Args: |
| product_id: The product ID (1-12) |
| """ |
| result = get_product_info_impl(product_id) |
| return str(result) |
|
|
|
|
| @function_tool |
| def find_product_for_goal(health_goal: str) -> str: |
| """Find products recommended for a specific health goal. |
| |
| Args: |
| health_goal: One of: weight_loss, immunity, energy, skin_health, digestion, detox |
| """ |
| result = find_product_for_goal_impl(health_goal) |
| return str(result) |
|
|
|
|
| @function_tool |
| def get_recipe_ideas(product_id: int = 0) -> str: |
| """Get recipe ideas for a product or general recipe suggestions. |
| |
| Args: |
| product_id: Optional product ID (1-12). Use 0 for general recipes. |
| """ |
| result = get_recipe_ideas_impl(product_id) |
| return str(result) |
|
|
|
|
| @function_tool |
| def compare_products(product_id_1: int, product_id_2: int) -> str: |
| """Compare two products side by side. |
| |
| Args: |
| product_id_1: First product ID |
| product_id_2: Second product ID |
| """ |
| result = compare_products_impl(product_id_1, product_id_2) |
| return str(result) |
|
|
|
|
| @function_tool |
| def check_price_and_delivery(product_id: int, city: str = "") -> str: |
| """Check product price and delivery charges for a city. |
| |
| Args: |
| product_id: The product ID |
| city: Delivery city (lahore, karachi, islamabad, rawalpindi, faisalabad, multan, peshawar, or other) |
| """ |
| result = check_price_and_delivery_impl(product_id, city) |
| return str(result) |
|
|
|
|
| @function_tool |
| def place_order(name: str, phone: str, address: str, products: list) -> str: |
| """Place a new order for the customer. |
| |
| Args: |
| name: Customer full name |
| phone: WhatsApp number |
| address: Full delivery address |
| products: List of dicts with product_id and quantity e.g. [{"product_id": 1, "quantity": 2}] |
| """ |
| result = place_order_impl(name, phone, address, products) |
| return str(result) |
|
|