1 Commits

Author SHA1 Message Date
Steve Androulakis
1b7c273e55 food ordering for stevea video 2025-05-31 01:07:08 -07:00
9 changed files with 463 additions and 0 deletions

View File

@@ -22,6 +22,12 @@ from .ecommerce.get_order import get_order
from .ecommerce.track_package import track_package
from .ecommerce.list_orders import list_orders
from .food.get_menu import get_menu
from .food.get_menu_item_details import get_menu_item_details
from .food.add_to_cart import add_to_cart
from .food.place_order import place_order
from .food.check_order_status import check_order_status
from .give_hint import give_hint
from .guess_location import guess_location
@@ -67,6 +73,16 @@ def get_handler(tool_name: str):
return track_package
if tool_name == "ListOrders":
return list_orders
if tool_name == "GetMenu":
return get_menu
if tool_name == "GetMenuItemDetails":
return get_menu_item_details
if tool_name == "AddToCart":
return add_to_cart
if tool_name == "PlaceOrder":
return place_order
if tool_name == "CheckOrderStatus":
return check_order_status
if tool_name == "GiveHint":
return give_hint
if tool_name == "GuessLocation":

View File

@@ -0,0 +1,122 @@
{
"restaurants": [
{
"id": "rest_001",
"name": "Tony's Pizza Palace",
"menu": [
{
"id": "item_001",
"name": "Margherita Pizza",
"category": "Pizza",
"price": 14.99,
"description": "Fresh mozzarella, tomato sauce, basil",
"available": true
},
{
"id": "item_002",
"name": "Pepperoni Pizza",
"category": "Pizza",
"price": 16.99,
"description": "Classic pepperoni with mozzarella and tomato sauce",
"available": true
},
{
"id": "item_003",
"name": "Caesar Salad",
"category": "Salad",
"price": 9.99,
"description": "Romaine lettuce, parmesan, croutons, caesar dressing",
"available": true
},
{
"id": "item_004",
"name": "Garlic Bread",
"category": "Sides",
"price": 5.99,
"description": "Fresh baked bread with garlic butter",
"available": true
},
{
"id": "item_005",
"name": "Tiramisu",
"category": "Dessert",
"price": 7.99,
"description": "Classic Italian dessert with coffee and mascarpone",
"available": true
}
]
}
],
"carts": {
"steve@example.com": {
"restaurant_id": "rest_001",
"items": []
}
},
"orders": [
{
"id": "order_001",
"customer_email": "john.doe@example.com",
"restaurant_id": "rest_001",
"items": [
{
"item_id": "item_001",
"quantity": 1,
"price": 14.99
},
{
"item_id": "item_004",
"quantity": 2,
"price": 5.99
}
],
"total": 26.97,
"status": "delivered",
"order_date": "2025-05-29T18:30:00Z",
"estimated_delivery": "2025-05-29T19:15:00Z",
"actual_delivery": "2025-05-29T19:12:00Z"
},
{
"id": "order_002",
"customer_email": "jane.smith@example.com",
"restaurant_id": "rest_001",
"items": [
{
"item_id": "item_002",
"quantity": 1,
"price": 16.99
}
],
"total": 16.99,
"status": "preparing",
"order_date": "2025-05-30T12:00:00Z",
"estimated_delivery": "2025-05-30T12:45:00Z"
},
{
"id": "order_58539a70",
"customer_email": "steve@example.com",
"restaurant_id": "rest_001",
"items": [
{
"item_id": "item_001",
"quantity": 1,
"price": 14.99
},
{
"item_id": "item_002",
"quantity": 1,
"price": 16.99
},
{
"item_id": "item_004",
"quantity": 1,
"price": 5.99
}
],
"total": 37.97,
"status": "preparing",
"order_date": "2025-05-30T20:28:18.444162Z",
"estimated_delivery": "2025-05-30T20:58:18.444169Z"
}
]
}

63
tools/food/add_to_cart.py Normal file
View File

@@ -0,0 +1,63 @@
from pathlib import Path
import json
def add_to_cart(args: dict) -> dict:
customer_email = args.get("customer_email")
item_id = args.get("item_id")
quantity = int(args.get("quantity", 1))
restaurant_id = args.get("restaurant_id", "rest_001")
file_path = Path(__file__).resolve().parent.parent / "data" / "food_ordering_data.json"
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
# Find the item to get its price
item_price = None
item_name = None
for restaurant in data["restaurants"]:
if restaurant["id"] == restaurant_id:
for item in restaurant["menu"]:
if item["id"] == item_id:
item_price = item["price"]
item_name = item["name"]
break
if item_price is None:
return {"error": f"Item {item_id} not found."}
# Initialize cart if it doesn't exist
if customer_email not in data["carts"]:
data["carts"][customer_email] = {
"restaurant_id": restaurant_id,
"items": []
}
# Check if item already in cart
cart = data["carts"][customer_email]
existing_item = None
for cart_item in cart["items"]:
if cart_item["item_id"] == item_id:
existing_item = cart_item
break
if existing_item:
existing_item["quantity"] += quantity
else:
cart["items"].append({
"item_id": item_id,
"quantity": quantity,
"price": item_price
})
# Save back to file
with open(file_path, "w") as file:
json.dump(data, file, indent=2)
return {
"status": "success",
"message": f"Added {quantity} x {item_name} to cart",
"cart": cart
}

View File

@@ -0,0 +1,28 @@
from pathlib import Path
import json
def check_order_status(args: dict) -> dict:
order_id = args.get("order_id")
file_path = Path(__file__).resolve().parent.parent / "data" / "food_ordering_data.json"
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
orders = data["orders"]
for order in orders:
if order["id"] == order_id:
return {
"order_id": order["id"],
"status": order["status"],
"order_date": order["order_date"],
"estimated_delivery": order["estimated_delivery"],
"actual_delivery": order.get("actual_delivery"),
"total": order["total"],
"items": order["items"]
}
return {"error": f"Order {order_id} not found."}

23
tools/food/get_menu.py Normal file
View File

@@ -0,0 +1,23 @@
from pathlib import Path
import json
def get_menu(args: dict) -> dict:
restaurant_id = args.get("restaurant_id", "rest_001")
file_path = Path(__file__).resolve().parent.parent / "data" / "food_ordering_data.json"
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
restaurants = data["restaurants"]
for restaurant in restaurants:
if restaurant["id"] == restaurant_id:
return {
"restaurant_name": restaurant["name"],
"menu": restaurant["menu"]
}
return {"error": f"Restaurant {restaurant_id} not found."}

View File

@@ -0,0 +1,23 @@
from pathlib import Path
import json
def get_menu_item_details(args: dict) -> dict:
item_id = args.get("item_id")
restaurant_id = args.get("restaurant_id", "rest_001")
file_path = Path(__file__).resolve().parent.parent / "data" / "food_ordering_data.json"
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
restaurants = data["restaurants"]
for restaurant in restaurants:
if restaurant["id"] == restaurant_id:
for item in restaurant["menu"]:
if item["id"] == item_id:
return item
return {"error": f"Menu item {item_id} not found."}

57
tools/food/place_order.py Normal file
View File

@@ -0,0 +1,57 @@
from pathlib import Path
import json
import uuid
from datetime import datetime, timedelta
def place_order(args: dict) -> dict:
customer_email = args.get("customer_email")
file_path = Path(__file__).resolve().parent.parent / "data" / "food_ordering_data.json"
if not file_path.exists():
return {"error": "Data file not found."}
with open(file_path, "r") as file:
data = json.load(file)
# Check if cart exists
if customer_email not in data["carts"] or not data["carts"][customer_email]["items"]:
return {"error": "Cart is empty. Please add items to cart first."}
cart = data["carts"][customer_email]
# Calculate total
total = sum(item["price"] * item["quantity"] for item in cart["items"])
# Create order
order_id = f"order_{str(uuid.uuid4())[:8]}"
order_date = datetime.now().isoformat() + "Z"
estimated_delivery = (datetime.now() + timedelta(minutes=30)).isoformat() + "Z"
new_order = {
"id": order_id,
"customer_email": customer_email,
"restaurant_id": cart["restaurant_id"],
"items": cart["items"],
"total": round(total, 2),
"status": "preparing",
"order_date": order_date,
"estimated_delivery": estimated_delivery
}
# Add order to data
data["orders"].append(new_order)
# Clear cart
data["carts"][customer_email] = {"restaurant_id": cart["restaurant_id"], "items": []}
# Save back to file
with open(file_path, "w") as file:
json.dump(data, file, indent=2)
return {
"status": "success",
"order_id": order_id,
"total": round(total, 2),
"estimated_delivery": estimated_delivery,
"message": "Order placed successfully!"
}

View File

@@ -454,6 +454,50 @@ goal_ecomm_list_orders = AgentGoal(
),
)
# ----- Food Ordering Goal -----
goal_food_ordering = AgentGoal(
id="goal_food_ordering",
category_tag="food",
agent_name="Food Ordering Assistant",
agent_friendly_description="Order food from Tony's Pizza Palace. Browse menu, add items to cart, and place orders.",
tools=[
tool_registry.food_get_menu_tool,
tool_registry.food_get_menu_item_details_tool,
tool_registry.food_add_to_cart_tool,
tool_registry.food_place_order_tool,
tool_registry.food_check_order_status_tool,
],
description="The user wants to order food from Tony's Pizza Palace. Help them browse the menu, learn about menu items, add items to their cart, and place an order. To assist with that goal, help the user gather args for these tools in order: "
"1. GetMenu: Show the restaurant menu. This tool is optional if the user already knows what they want. "
"2. GetMenuItemDetails: Get details about specific menu items. This tool is optional and can be used multiple times. "
"3. AddToCart: Add menu items to the customer's cart. This tool can be used multiple times to add different items. "
"4. PlaceOrder: Place the order for items in the cart. "
"5. CheckOrderStatus: Check the status of a placed order. This tool is optional and used after placing an order.",
starter_prompt=starter_prompt_generic,
example_conversation_history="\n ".join(
[
"user: I'd like to order some food",
"agent: Great! I can help you order food from Tony's Pizza Palace. Would you like to see the menu first?",
"user: Yes, please show me the menu",
"user_confirmed_tool_run: <user clicks confirm on GetMenu tool>",
"tool_result: {'restaurant_name': 'Tony\\'s Pizza Palace', 'menu': [{'id': 'item_001', 'name': 'Margherita Pizza', 'category': 'Pizza', 'price': 14.99, 'description': 'Fresh mozzarella, tomato sauce, basil', 'available': True}, {'id': 'item_002', 'name': 'Pepperoni Pizza', 'category': 'Pizza', 'price': 16.99, 'description': 'Classic pepperoni with mozzarella and tomato sauce', 'available': True}]}",
"agent: Here's the menu from Tony's Pizza Palace: \n"
"Pizza: \n"
"- Margherita Pizza ($14.99): Fresh mozzarella, tomato sauce, basil \n"
"- Pepperoni Pizza ($16.99): Classic pepperoni with mozzarella and tomato sauce \n"
"What would you like to add to your cart? I'll need your email address to create your order.",
"user: I'd like a Margherita Pizza. My email is john.doe@example.com",
"user_confirmed_tool_run: <user clicks confirm on AddToCart tool>",
"tool_result: {'status': 'success', 'message': 'Added 1 x Margherita Pizza to cart', 'cart': {'restaurant_id': 'rest_001', 'items': [{'item_id': 'item_001', 'quantity': 1, 'price': 14.99}]}}",
"agent: Perfect! I've added 1 Margherita Pizza to your cart. Would you like to add anything else or are you ready to place your order?",
"user: I'm ready to place the order",
"user_confirmed_tool_run: <user clicks confirm on PlaceOrder tool>",
"tool_result: {'status': 'success', 'order_id': 'order_12345678', 'total': 14.99, 'estimated_delivery': '2025-05-30T13:30:00Z', 'message': 'Order placed successfully!'}",
"agent: Order placed successfully! Your order ID is order_12345678 and the total is $14.99. Your food should be delivered by 1:30 PM today. You can check your order status anytime using the order ID.",
]
),
)
# Add the goals to a list for more generic processing, like listing available agents
goal_list: List[AgentGoal] = []
goal_list.append(goal_choose_agent_type)
@@ -468,6 +512,7 @@ goal_list.append(goal_fin_move_money)
goal_list.append(goal_fin_loan_application)
goal_list.append(goal_ecomm_list_orders)
goal_list.append(goal_ecomm_order_status)
goal_list.append(goal_food_ordering)
# for multi-goal, just set list agents as the last tool

View File

@@ -397,3 +397,89 @@ ecomm_track_package = ToolDefinition(
),
],
)
# ----- Food Ordering Use Case Tools -----
food_get_menu_tool = ToolDefinition(
name="GetMenu",
description="Get the menu for a restaurant. Defaults to Tony's Pizza Palace if no restaurant specified.",
arguments=[
ToolArgument(
name="restaurant_id",
type="string",
description="ID of the restaurant (defaults to rest_001 for Tony's Pizza Palace)",
),
],
)
food_get_menu_item_details_tool = ToolDefinition(
name="GetMenuItemDetails",
description="Get detailed information about a specific menu item.",
arguments=[
ToolArgument(
name="item_id",
type="string",
description="ID of the menu item to get details for",
),
ToolArgument(
name="restaurant_id",
type="string",
description="ID of the restaurant (defaults to rest_001 for Tony's Pizza Palace)",
),
],
)
food_add_to_cart_tool = ToolDefinition(
name="AddToCart",
description="Add a menu item to the customer's cart.",
arguments=[
ToolArgument(
name="customer_email",
type="string",
description="Email address of the customer",
),
ToolArgument(
name="item_id",
type="string",
description="ID of the menu item to add to cart",
),
ToolArgument(
name="quantity",
type="number",
description="Quantity of the item to add (defaults to 1)",
),
ToolArgument(
name="restaurant_id",
type="string",
description="ID of the restaurant (defaults to rest_001 for Tony's Pizza Palace)",
),
],
)
food_place_order_tool = ToolDefinition(
name="PlaceOrder",
description="Place an order for the items in the customer's cart.",
arguments=[
ToolArgument(
name="customer_email",
type="string",
description="Email address of the customer",
),
ToolArgument(
name="userConfirmation",
type="string",
description="Indication of user's desire to place the order",
),
],
)
food_check_order_status_tool = ToolDefinition(
name="CheckOrderStatus",
description="Check the status of a food order.",
arguments=[
ToolArgument(
name="order_id",
type="string",
description="ID of the order to check status for",
),
],
)