ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# Copyright Sierra
|
||||
|
||||
from .book_reservation import BookReservation
|
||||
from .calculate import Calculate
|
||||
from .cancel_reservation import CancelReservation
|
||||
from .get_reservation_details import GetReservationDetails
|
||||
from .get_user_details import GetUserDetails
|
||||
from .list_all_airports import ListAllAirports
|
||||
from .search_direct_flight import SearchDirectFlight
|
||||
from .search_onestop_flight import SearchOnestopFlight
|
||||
from .send_certificate import SendCertificate
|
||||
from .think import Think
|
||||
from .transfer_to_human_agents import TransferToHumanAgents
|
||||
from .update_reservation_baggages import UpdateReservationBaggages
|
||||
from .update_reservation_flights import UpdateReservationFlights
|
||||
from .update_reservation_passengers import UpdateReservationPassengers
|
||||
|
||||
ALL_TOOLS = [
|
||||
BookReservation,
|
||||
Calculate,
|
||||
CancelReservation,
|
||||
GetReservationDetails,
|
||||
GetUserDetails,
|
||||
ListAllAirports,
|
||||
SearchDirectFlight,
|
||||
SearchOnestopFlight,
|
||||
SendCertificate,
|
||||
Think,
|
||||
TransferToHumanAgents,
|
||||
UpdateReservationBaggages,
|
||||
UpdateReservationFlights,
|
||||
UpdateReservationPassengers,
|
||||
]
|
||||
@@ -0,0 +1,226 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from copy import deepcopy
|
||||
from typing import Any, Dict, List
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class BookReservation(Tool):
|
||||
@staticmethod
|
||||
def invoke(
|
||||
data: Dict[str, Any],
|
||||
user_id: str,
|
||||
origin: str,
|
||||
destination: str,
|
||||
flight_type: str,
|
||||
cabin: str,
|
||||
flights: List[Dict[str, Any]],
|
||||
passengers: List[Dict[str, Any]],
|
||||
payment_methods: List[Dict[str, Any]],
|
||||
total_baggages: int,
|
||||
nonfree_baggages: int,
|
||||
insurance: str,
|
||||
) -> str:
|
||||
reservations, users = data["reservations"], data["users"]
|
||||
if user_id not in users:
|
||||
return "Error: user not found"
|
||||
user = users[user_id]
|
||||
|
||||
# assume each task makes at most 3 reservations
|
||||
reservation_id = "HATHAT"
|
||||
if reservation_id in reservations:
|
||||
reservation_id = "HATHAU"
|
||||
if reservation_id in reservations:
|
||||
reservation_id = "HATHAV"
|
||||
|
||||
reservation = {
|
||||
"reservation_id": reservation_id,
|
||||
"user_id": user_id,
|
||||
"origin": origin,
|
||||
"destination": destination,
|
||||
"flight_type": flight_type,
|
||||
"cabin": cabin,
|
||||
"flights": deepcopy(flights),
|
||||
"passengers": passengers,
|
||||
"payment_history": payment_methods,
|
||||
"created_at": "2024-05-15T15:00:00",
|
||||
"total_baggages": total_baggages,
|
||||
"nonfree_baggages": nonfree_baggages,
|
||||
"insurance": insurance,
|
||||
}
|
||||
|
||||
# update flights and calculate price
|
||||
total_price = 0
|
||||
for flight in reservation["flights"]:
|
||||
flight_number = flight["flight_number"]
|
||||
if flight_number not in data["flights"]:
|
||||
return f"Error: flight {flight_number} not found"
|
||||
flight_data = data["flights"][flight_number]
|
||||
if flight["date"] not in flight_data["dates"]:
|
||||
return (
|
||||
f"Error: flight {flight_number} not found on date {flight['date']}"
|
||||
)
|
||||
flight_date_data = flight_data["dates"][flight["date"]]
|
||||
if flight_date_data["status"] != "available":
|
||||
return f"Error: flight {flight_number} not available on date {flight['date']}"
|
||||
if flight_date_data["available_seats"][cabin] < len(passengers):
|
||||
return f"Error: not enough seats on flight {flight_number}"
|
||||
flight["price"] = flight_date_data["prices"][cabin]
|
||||
flight["origin"] = flight_data["origin"]
|
||||
flight["destination"] = flight_data["destination"]
|
||||
total_price += flight["price"] * len(passengers)
|
||||
|
||||
if insurance == "yes":
|
||||
total_price += 30 * len(passengers)
|
||||
|
||||
total_price += 50 * nonfree_baggages
|
||||
|
||||
for payment_method in payment_methods:
|
||||
payment_id = payment_method["payment_id"]
|
||||
amount = payment_method["amount"]
|
||||
if payment_id not in user["payment_methods"]:
|
||||
return f"Error: payment method {payment_id} not found"
|
||||
if user["payment_methods"][payment_id]["source"] in [
|
||||
"gift_card",
|
||||
"certificate",
|
||||
]:
|
||||
if user["payment_methods"][payment_id]["amount"] < amount:
|
||||
return f"Error: not enough balance in payment method {payment_id}"
|
||||
if sum(payment["amount"] for payment in payment_methods) != total_price:
|
||||
return f"Error: payment amount does not add up, total price is {total_price}, but paid {sum(payment['amount'] for payment in payment_methods)}"
|
||||
|
||||
# if checks pass, deduct payment and update seats
|
||||
for payment_method in payment_methods:
|
||||
payment_id = payment_method["payment_id"]
|
||||
amount = payment_method["amount"]
|
||||
if user["payment_methods"][payment_id]["source"] == "gift_card":
|
||||
user["payment_methods"][payment_id]["amount"] -= amount
|
||||
elif user["payment_methods"][payment_id]["source"] == "certificate":
|
||||
del user["payment_methods"][payment_id]
|
||||
|
||||
reservations[reservation_id] = reservation
|
||||
user["reservations"].append(reservation_id)
|
||||
return json.dumps(reservation)
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "book_reservation",
|
||||
"description": "Book a reservation.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the user to book the reservation, such as 'sara_doe_496'.",
|
||||
},
|
||||
"origin": {
|
||||
"type": "string",
|
||||
"description": "The IATA code for the origin city, such as 'SFO'.",
|
||||
},
|
||||
"destination": {
|
||||
"type": "string",
|
||||
"description": "The IATA code for the destination city, such as 'JFK'.",
|
||||
},
|
||||
"flight_type": {
|
||||
"type": "string",
|
||||
"enum": ["one_way", "round_trip"],
|
||||
},
|
||||
"cabin": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"basic_economy",
|
||||
"economy",
|
||||
"business",
|
||||
],
|
||||
},
|
||||
"flights": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing details about each piece of flight.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"flight_number": {
|
||||
"type": "string",
|
||||
"description": "Flight number, such as 'HAT001'.",
|
||||
},
|
||||
"date": {
|
||||
"type": "string",
|
||||
"description": "The date for the flight in the format 'YYYY-MM-DD', such as '2024-05-01'.",
|
||||
},
|
||||
},
|
||||
"required": ["flight_number", "date"],
|
||||
},
|
||||
},
|
||||
"passengers": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing details about each passenger.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string",
|
||||
"description": "The first name of the passenger, such as 'Noah'.",
|
||||
},
|
||||
"last_name": {
|
||||
"type": "string",
|
||||
"description": "The last name of the passenger, such as 'Brown'.",
|
||||
},
|
||||
"dob": {
|
||||
"type": "string",
|
||||
"description": "The date of birth of the passenger in the format 'YYYY-MM-DD', such as '1990-01-01'.",
|
||||
},
|
||||
},
|
||||
"required": ["first_name", "last_name", "dob"],
|
||||
},
|
||||
},
|
||||
"payment_methods": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing details about each payment method.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"payment_id": {
|
||||
"type": "string",
|
||||
"description": "The payment id stored in user profile, such as 'credit_card_7815826', 'gift_card_7815826', 'certificate_7815826'.",
|
||||
},
|
||||
"amount": {
|
||||
"type": "number",
|
||||
"description": "The amount to be paid.",
|
||||
},
|
||||
},
|
||||
"required": ["payment_id", "amount"],
|
||||
},
|
||||
},
|
||||
"total_baggages": {
|
||||
"type": "integer",
|
||||
"description": "The total number of baggage items included in the reservation.",
|
||||
},
|
||||
"nonfree_baggages": {
|
||||
"type": "integer",
|
||||
"description": "The number of non-free baggage items included in the reservation.",
|
||||
},
|
||||
"insurance": {
|
||||
"type": "string",
|
||||
"enum": ["yes", "no"],
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"user_id",
|
||||
"origin",
|
||||
"destination",
|
||||
"flight_type",
|
||||
"cabin",
|
||||
"flights",
|
||||
"passengers",
|
||||
"payment_methods",
|
||||
"total_baggages",
|
||||
"nonfree_baggages",
|
||||
"insurance",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Copyright Sierra
|
||||
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class Calculate(Tool):
|
||||
@staticmethod
|
||||
def invoke(data: Dict[str, Any], expression: str) -> str:
|
||||
if not all(char in "0123456789+-*/(). " for char in expression):
|
||||
return "Error: invalid characters in expression"
|
||||
try:
|
||||
return str(round(float(eval(expression, {"__builtins__": None}, {})), 2))
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "calculate",
|
||||
"description": "Calculate the result of a mathematical expression.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"expression": {
|
||||
"type": "string",
|
||||
"description": "The mathematical expression to calculate, such as '2 + 2'. The expression can contain numbers, operators (+, -, *, /), parentheses, and spaces.",
|
||||
},
|
||||
},
|
||||
"required": ["expression"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class CancelReservation(Tool):
|
||||
@staticmethod
|
||||
def invoke(
|
||||
data: Dict[str, Any],
|
||||
reservation_id: str,
|
||||
) -> str:
|
||||
reservations = data["reservations"]
|
||||
if reservation_id not in reservations:
|
||||
return "Error: reservation not found"
|
||||
reservation = reservations[reservation_id]
|
||||
|
||||
# reverse the payment
|
||||
refunds = []
|
||||
for payment in reservation["payment_history"]:
|
||||
refunds.append(
|
||||
{
|
||||
"payment_id": payment["payment_id"],
|
||||
"amount": -payment["amount"],
|
||||
}
|
||||
)
|
||||
reservation["payment_history"].extend(refunds)
|
||||
reservation["status"] = "cancelled"
|
||||
return json.dumps(reservation)
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "cancel_reservation",
|
||||
"description": "Cancel the whole reservation.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reservation_id": {
|
||||
"type": "string",
|
||||
"description": "The reservation ID, such as 'ZFA04Y'.",
|
||||
},
|
||||
},
|
||||
"required": ["reservation_id"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class GetReservationDetails(Tool):
|
||||
@staticmethod
|
||||
def invoke(data: Dict[str, Any], reservation_id: str) -> str:
|
||||
reservations = data["reservations"]
|
||||
if reservation_id in reservations:
|
||||
return json.dumps(reservations[reservation_id])
|
||||
return "Error: user not found"
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_reservation_details",
|
||||
"description": "Get the details of a reservation.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reservation_id": {
|
||||
"type": "string",
|
||||
"description": "The reservation id, such as '8JX2WO'.",
|
||||
},
|
||||
},
|
||||
"required": ["reservation_id"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class GetUserDetails(Tool):
|
||||
@staticmethod
|
||||
def invoke(data: Dict[str, Any], user_id: str) -> str:
|
||||
users = data["users"]
|
||||
if user_id in users:
|
||||
return json.dumps(users[user_id])
|
||||
return "Error: user not found"
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_user_details",
|
||||
"description": "Get the details of an user, including their reservations.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"description": "The user id, such as 'sara_doe_496'.",
|
||||
},
|
||||
},
|
||||
"required": ["user_id"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class ListAllAirports(Tool):
|
||||
@staticmethod
|
||||
def invoke(data: Dict[str, Any]) -> str:
|
||||
airports = [
|
||||
"SFO",
|
||||
"JFK",
|
||||
"LAX",
|
||||
"ORD",
|
||||
"DFW",
|
||||
"DEN",
|
||||
"SEA",
|
||||
"ATL",
|
||||
"MIA",
|
||||
"BOS",
|
||||
"PHX",
|
||||
"IAH",
|
||||
"LAS",
|
||||
"MCO",
|
||||
"EWR",
|
||||
"CLT",
|
||||
"MSP",
|
||||
"DTW",
|
||||
"PHL",
|
||||
"LGA",
|
||||
]
|
||||
cities = [
|
||||
"San Francisco",
|
||||
"New York",
|
||||
"Los Angeles",
|
||||
"Chicago",
|
||||
"Dallas",
|
||||
"Denver",
|
||||
"Seattle",
|
||||
"Atlanta",
|
||||
"Miami",
|
||||
"Boston",
|
||||
"Phoenix",
|
||||
"Houston",
|
||||
"Las Vegas",
|
||||
"Orlando",
|
||||
"Newark",
|
||||
"Charlotte",
|
||||
"Minneapolis",
|
||||
"Detroit",
|
||||
"Philadelphia",
|
||||
"LaGuardia",
|
||||
]
|
||||
return json.dumps({airport: city for airport, city in zip(airports, cities)})
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "list_all_airports",
|
||||
"description": "List all airports and their cities.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": [],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class SearchDirectFlight(Tool):
|
||||
@staticmethod
|
||||
def invoke(data: Dict[str, Any], origin: str, destination: str, date: str) -> str:
|
||||
flights = data["flights"]
|
||||
results = []
|
||||
for flight in flights.values():
|
||||
if flight["origin"] == origin and flight["destination"] == destination:
|
||||
if (
|
||||
date in flight["dates"]
|
||||
and flight["dates"][date]["status"] == "available"
|
||||
):
|
||||
# results add flight except dates, but add flight["datas"][date]
|
||||
results.append({k: v for k, v in flight.items() if k != "dates"})
|
||||
results[-1].update(flight["dates"][date])
|
||||
return json.dumps(results)
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "search_direct_flight",
|
||||
"description": "Search direct flights between two cities on a specific date.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"origin": {
|
||||
"type": "string",
|
||||
"description": "The origin city airport in three letters, such as 'JFK'.",
|
||||
},
|
||||
"destination": {
|
||||
"type": "string",
|
||||
"description": "The destination city airport in three letters, such as 'LAX'.",
|
||||
},
|
||||
"date": {
|
||||
"type": "string",
|
||||
"description": "The date of the flight in the format 'YYYY-MM-DD', such as '2024-01-01'.",
|
||||
},
|
||||
},
|
||||
"required": ["origin", "destination", "date"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class SearchOnestopFlight(Tool):
|
||||
@staticmethod
|
||||
def invoke(data: Dict[str, Any], origin: str, destination: str, date: str) -> str:
|
||||
flights = data["flights"]
|
||||
results = []
|
||||
for flight1 in flights.values():
|
||||
if flight1["origin"] == origin:
|
||||
for flight2 in flights.values():
|
||||
if (
|
||||
flight2["destination"] == destination
|
||||
and flight1["destination"] == flight2["origin"]
|
||||
):
|
||||
date2 = (
|
||||
f"2024-05-{int(date[-2:])+1}"
|
||||
if "+1" in flight1["scheduled_arrival_time_est"]
|
||||
else date
|
||||
)
|
||||
if (
|
||||
flight1["scheduled_arrival_time_est"]
|
||||
> flight2["scheduled_departure_time_est"]
|
||||
):
|
||||
continue
|
||||
if date in flight1["dates"] and date2 in flight2["dates"]:
|
||||
if (
|
||||
flight1["dates"][date]["status"] == "available"
|
||||
and flight2["dates"][date2]["status"] == "available"
|
||||
):
|
||||
result1 = {
|
||||
k: v for k, v in flight1.items() if k != "dates"
|
||||
}
|
||||
result1.update(flight1["dates"][date])
|
||||
result1["date"] = date
|
||||
result2 = {
|
||||
k: v for k, v in flight2.items() if k != "dates"
|
||||
}
|
||||
result2.update(flight2["dates"][date])
|
||||
result2["date"] = date2
|
||||
results.append([result1, result2])
|
||||
return json.dumps(results)
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "search_onestop_flight",
|
||||
"description": "Search direct flights between two cities on a specific date.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"origin": {
|
||||
"type": "string",
|
||||
"description": "The origin city airport in three letters, such as 'JFK'.",
|
||||
},
|
||||
"destination": {
|
||||
"type": "string",
|
||||
"description": "The destination city airport in three letters, such as 'LAX'.",
|
||||
},
|
||||
"date": {
|
||||
"type": "string",
|
||||
"description": "The date of the flight in the format 'YYYY-MM-DD', such as '2024-05-01'.",
|
||||
},
|
||||
},
|
||||
"required": ["origin", "destination", "date"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
# Copyright Sierra
|
||||
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class SendCertificate(Tool):
|
||||
@staticmethod
|
||||
def invoke(
|
||||
data: Dict[str, Any],
|
||||
user_id: str,
|
||||
amount: int,
|
||||
) -> str:
|
||||
users = data["users"]
|
||||
if user_id not in users:
|
||||
return "Error: user not found"
|
||||
user = users[user_id]
|
||||
|
||||
# add a certificate, assume at most 3 cases per task
|
||||
for id in [3221322, 3221323, 3221324]:
|
||||
payment_id = f"certificate_{id}"
|
||||
if payment_id not in user["payment_methods"]:
|
||||
user["payment_methods"][payment_id] = {
|
||||
"source": "certificate",
|
||||
"amount": amount,
|
||||
"id": payment_id,
|
||||
}
|
||||
return f"Certificate {payment_id} added to user {user_id} with amount {amount}."
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "send_certificate",
|
||||
"description": "Send a certificate to a user. Be careful!",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"description": "The ID of the user to book the reservation, such as 'sara_doe_496'.",
|
||||
},
|
||||
"amount": {
|
||||
"type": "number",
|
||||
"description": "Certificate amount to send.",
|
||||
},
|
||||
},
|
||||
"required": ["user_id", "amount"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
# Copyright Sierra
|
||||
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class Think(Tool):
|
||||
@staticmethod
|
||||
def invoke(data: Dict[str, Any], thought: str) -> str:
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "think",
|
||||
"description": "Use the tool to think about something. It will not obtain new information or change the database, but just append the thought to the log. Use it when complex reasoning is needed.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"thought": {
|
||||
"type": "string",
|
||||
"description": "A thought to think about.",
|
||||
},
|
||||
},
|
||||
"required": ["thought"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Copyright Sierra
|
||||
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class TransferToHumanAgents(Tool):
|
||||
@staticmethod
|
||||
def invoke(
|
||||
data: Dict[str, Any],
|
||||
summary: str,
|
||||
) -> str:
|
||||
return "Transfer successful"
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "transfer_to_human_agents",
|
||||
"description": "Transfer the user to a human agent, with a summary of the user's issue. Only transfer if the user explicitly asks for a human agent, or if the user's issue cannot be resolved by the agent with the available tools.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"description": "A summary of the user's issue.",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"summary",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class UpdateReservationBaggages(Tool):
|
||||
@staticmethod
|
||||
def invoke(
|
||||
data: Dict[str, Any],
|
||||
reservation_id: str,
|
||||
total_baggages: int,
|
||||
nonfree_baggages: int,
|
||||
payment_id: str,
|
||||
) -> str:
|
||||
users, reservations = data["users"], data["reservations"]
|
||||
if reservation_id not in reservations:
|
||||
return "Error: reservation not found"
|
||||
reservation = reservations[reservation_id]
|
||||
|
||||
total_price = 50 * max(0, nonfree_baggages - reservation["nonfree_baggages"])
|
||||
if payment_id not in users[reservation["user_id"]]["payment_methods"]:
|
||||
return "Error: payment method not found"
|
||||
payment_method = users[reservation["user_id"]]["payment_methods"][payment_id]
|
||||
if payment_method["source"] == "certificate":
|
||||
return "Error: certificate cannot be used to update reservation"
|
||||
elif (
|
||||
payment_method["source"] == "gift_card"
|
||||
and payment_method["amount"] < total_price
|
||||
):
|
||||
return "Error: gift card balance is not enough"
|
||||
|
||||
reservation["total_baggages"] = total_baggages
|
||||
reservation["nonfree_baggages"] = nonfree_baggages
|
||||
if payment_method["source"] == "gift_card":
|
||||
payment_method["amount"] -= total_price
|
||||
|
||||
if total_price != 0:
|
||||
reservation["payment_history"].append(
|
||||
{
|
||||
"payment_id": payment_id,
|
||||
"amount": total_price,
|
||||
}
|
||||
)
|
||||
|
||||
return json.dumps(reservation)
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "update_reservation_baggages",
|
||||
"description": "Update the baggage information of a reservation.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reservation_id": {
|
||||
"type": "string",
|
||||
"description": "The reservation ID, such as 'ZFA04Y'.",
|
||||
},
|
||||
"total_baggages": {
|
||||
"type": "integer",
|
||||
"description": "The updated total number of baggage items included in the reservation.",
|
||||
},
|
||||
"nonfree_baggages": {
|
||||
"type": "integer",
|
||||
"description": "The updated number of non-free baggage items included in the reservation.",
|
||||
},
|
||||
"payment_id": {
|
||||
"type": "string",
|
||||
"description": "The payment id stored in user profile, such as 'credit_card_7815826', 'gift_card_7815826', 'certificate_7815826'.",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"reservation_id",
|
||||
"total_baggages",
|
||||
"nonfree_baggages",
|
||||
"payment_id",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from copy import deepcopy
|
||||
from typing import Any, Dict, List
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class UpdateReservationFlights(Tool):
|
||||
@staticmethod
|
||||
def invoke(
|
||||
data: Dict[str, Any],
|
||||
reservation_id: str,
|
||||
cabin: str,
|
||||
flights: List[Dict[str, Any]],
|
||||
payment_id: str,
|
||||
) -> str:
|
||||
users, reservations = data["users"], data["reservations"]
|
||||
if reservation_id not in reservations:
|
||||
return "Error: reservation not found"
|
||||
reservation = reservations[reservation_id]
|
||||
|
||||
# update flights and calculate price
|
||||
total_price = 0
|
||||
flights = deepcopy(flights)
|
||||
for flight in flights:
|
||||
# if existing flight, ignore
|
||||
if _ := [
|
||||
f
|
||||
for f in reservation["flights"]
|
||||
if f["flight_number"] == flight["flight_number"]
|
||||
and f["date"] == flight["date"]
|
||||
and cabin == reservation["cabin"]
|
||||
]:
|
||||
total_price += _[0]["price"] * len(reservation["passengers"])
|
||||
flight["price"] = _[0]["price"]
|
||||
flight["origin"] = _[0]["origin"]
|
||||
flight["destination"] = _[0]["destination"]
|
||||
continue
|
||||
flight_number = flight["flight_number"]
|
||||
if flight_number not in data["flights"]:
|
||||
return f"Error: flight {flight_number} not found"
|
||||
flight_data = data["flights"][flight_number]
|
||||
if flight["date"] not in flight_data["dates"]:
|
||||
return (
|
||||
f"Error: flight {flight_number} not found on date {flight['date']}"
|
||||
)
|
||||
flight_date_data = flight_data["dates"][flight["date"]]
|
||||
if flight_date_data["status"] != "available":
|
||||
return f"Error: flight {flight_number} not available on date {flight['date']}"
|
||||
if flight_date_data["available_seats"][cabin] < len(
|
||||
reservation["passengers"]
|
||||
):
|
||||
return f"Error: not enough seats on flight {flight_number}"
|
||||
flight["price"] = flight_date_data["prices"][cabin]
|
||||
flight["origin"] = flight_data["origin"]
|
||||
flight["destination"] = flight_data["destination"]
|
||||
total_price += flight["price"] * len(reservation["passengers"])
|
||||
|
||||
total_price -= sum(flight["price"] for flight in reservation["flights"]) * len(
|
||||
reservation["passengers"]
|
||||
)
|
||||
|
||||
# check payment
|
||||
if payment_id not in users[reservation["user_id"]]["payment_methods"]:
|
||||
return "Error: payment method not found"
|
||||
payment_method = users[reservation["user_id"]]["payment_methods"][payment_id]
|
||||
if payment_method["source"] == "certificate":
|
||||
return "Error: certificate cannot be used to update reservation"
|
||||
elif (
|
||||
payment_method["source"] == "gift_card"
|
||||
and payment_method["amount"] < total_price
|
||||
):
|
||||
return "Error: gift card balance is not enough"
|
||||
|
||||
# if checks pass, deduct payment and update seats
|
||||
if payment_method["source"] == "gift_card":
|
||||
payment_method["amount"] -= total_price
|
||||
reservation["flights"] = flights
|
||||
if total_price != 0:
|
||||
reservation["payment_history"].append(
|
||||
{
|
||||
"payment_id": payment_id,
|
||||
"amount": total_price,
|
||||
}
|
||||
)
|
||||
# do not make flight database update here, assume it takes time to be updated
|
||||
return json.dumps(reservation)
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "update_reservation_flights",
|
||||
"description": "Update the flight information of a reservation.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reservation_id": {
|
||||
"type": "string",
|
||||
"description": "The reservation ID, such as 'ZFA04Y'.",
|
||||
},
|
||||
"cabin": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"basic_economy",
|
||||
"economy",
|
||||
"business",
|
||||
],
|
||||
},
|
||||
"flights": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing details about each piece of flight in the ENTIRE new reservation. Even if the a flight segment is not changed, it should still be included in the array.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"flight_number": {
|
||||
"type": "string",
|
||||
"description": "Flight number, such as 'HAT001'.",
|
||||
},
|
||||
"date": {
|
||||
"type": "string",
|
||||
"description": "The date for the flight in the format 'YYYY-MM-DD', such as '2024-05-01'.",
|
||||
},
|
||||
},
|
||||
"required": ["flight_number", "date"],
|
||||
},
|
||||
},
|
||||
"payment_id": {
|
||||
"type": "string",
|
||||
"description": "The payment id stored in user profile, such as 'credit_card_7815826', 'gift_card_7815826', 'certificate_7815826'.",
|
||||
},
|
||||
},
|
||||
"required": ["reservation_id", "cabin", "flights", "payment_id"],
|
||||
},
|
||||
},
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
# Copyright Sierra
|
||||
|
||||
import json
|
||||
from typing import Any, Dict, List
|
||||
from tau_bench.envs.tool import Tool
|
||||
|
||||
|
||||
class UpdateReservationPassengers(Tool):
|
||||
@staticmethod
|
||||
def invoke(
|
||||
data: Dict[str, Any],
|
||||
reservation_id: str,
|
||||
passengers: List[Dict[str, Any]],
|
||||
) -> str:
|
||||
reservations = data["reservations"]
|
||||
if reservation_id not in reservations:
|
||||
return "Error: reservation not found"
|
||||
reservation = reservations[reservation_id]
|
||||
if len(passengers) != len(reservation["passengers"]):
|
||||
return "Error: number of passengers does not match"
|
||||
reservation["passengers"] = passengers
|
||||
return json.dumps(reservation)
|
||||
|
||||
@staticmethod
|
||||
def get_info() -> Dict[str, Any]:
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "update_reservation_passengers",
|
||||
"description": "Update the passenger information of a reservation.",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"reservation_id": {
|
||||
"type": "string",
|
||||
"description": "The reservation ID, such as 'ZFA04Y'.",
|
||||
},
|
||||
"passengers": {
|
||||
"type": "array",
|
||||
"description": "An array of objects containing details about each passenger.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": "string",
|
||||
"description": "The first name of the passenger, such as 'Noah'.",
|
||||
},
|
||||
"last_name": {
|
||||
"type": "string",
|
||||
"description": "The last name of the passenger, such as 'Brown'.",
|
||||
},
|
||||
"dob": {
|
||||
"type": "string",
|
||||
"description": "The date of birth of the passenger in the format 'YYYY-MM-DD', such as '1990-01-01'.",
|
||||
},
|
||||
},
|
||||
"required": ["first_name", "last_name", "dob"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"required": ["reservation_id", "passengers"],
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user