The Refraction API | Tool Calling¶
In the previous chapter, we discussed the basic form of the refraction API, where you have the catalog specs, and the generated tool call(s), in structured forms and you want to validate, and act upon the results of the validation, within an agentic system.
This chapter will describe a less invasive form where you can annotate tools directly for this purpose.
3.1 Decorating a Tool¶
Let's start with tool / function calls outside of existing agentic frameworks. Consider the following tools.
from refraction.integration import refract
@refract()
def SkyScrapperFlightSearch(
originSkyId: str,
destinationSkyId: str,
originEntityId: str,
destinationEntityId: str,
date: str,
returnDate: Optional[str] = None,
cabinClass: Optional[str] = "economy",
adults: Optional[int] = 1,
...
) -> Dict[str, Any]:
return {...}
@refract()
def TripadvisorSearchLocation(
query: str,
) -> Dict[str, Any]:
return {...}
@refract(
api="TripadvisorSearchHotels",
use_given_operators_only=False,
execute_if_fixed=True,
)
def search_hotels(**kwargs: Any) -> Dict[str, Any]:
return {...}
A couple of things to notice here. The tools or function can be in two forms: either the signature itself contains what all it needs (if it wraps an API inside, then these would be the input specification of that API). This is not always possible, and so the refract decorator allows you to annotate with the name of the API it is wrapping instead.
3.1.1 Successful Call¶
This is a successful call (notice the extra inputs) and the function will execute as if nothing extra has happened!
flight_details = SkyScrapperFlightSearch(
originSkyId="BOS",
destinationSkyId="JFK",
originEntityId="123",
destinationEntityId="456",
date="2024-05-09",
# NOTE: Extra parameter
refractor=refractor,
)
3.1.2 Faulty Call with Return¶
Now we have missed a parameter in the call.
flight_details = SkyScrapperFlightSearch(
# missing parameter
# originSkyId="BOS",
destinationSkyId="JFK",
originEntityId="123",
destinationEntityId="456",
date="2024-05-09",
# NOTE: Extra parameters
refractor=self.refractor,
)
The decorator will block the call and return a refraction result instead. As described in the previous chapter, you can use this to decide how to fix your call.
+ ask(originSkyId)
- var1 = SkyScrapperFlightSearch(destinationSkyId="JFK", originEntityId="123", destinationEntityId="456", date="2024-05-09")
+ var1 = SkyScrapperFlightSearch(destinationSkyId="JFK", originEntityId="123", destinationEntityId="456", date="2024-05-09", originSkyId="$originSkyId$")
? +++++++++++++++++++++++++++++
3.1.3 Faulty Call with Execution¶
If this call is fixable as is, then setting the following parameter, lets the fixed call to execute in place without returning back to the user, even if the original function call was incomplete / incorrect.
memory = {"query": "London", "var1": {"geoId": "foo"}}
payload = {
"checkIn": "2024-09-05",
"checkOut": "2024-09-15",
}
result = search_hotels(
**payload,
refractor=refractor,
memory=memory,
)
- var2 = TripadvisorSearchHotels(checkIn="2024-09-05", checkOut="2024-09-15")
+ var2 = TripadvisorSearchHotels(checkIn="2024-09-05", checkOut="2024-09-15", geoId="$var1.geoId$")
? ++++++++++++++++++++++
3.1.4 Recovery Call¶
Now we have messed up the call in a way that can be fixed by making an extra call! This will be allowed if you set the following parameter.
memory = {
"query": "London",
}
payload = {
"geoId": "$var1.geoId$",
"checkIn": "2024-09-05",
"checkOut": "2024-09-15",
}
hotel_details = search_hotels(
param="foo", **payload, refractor=refractor, memory=memory,
)
Notice the extra call! 🤯 You will now get the result of executing the whole sequence in response to making the original faulty call.
+ var1 = TripadvisorSearchLocation(query="$query$")
- var1 = TripadvisorSearchHotels(param="foo", geoId="$var1.geoId$", checkIn="2024-09-05", checkOut="2024-09-15")
? -------------
+ var1 = TripadvisorSearchHotels(geoId="$var1.geoId$", checkIn="2024-09-05", checkOut="2024-09-15")
Executing: var1 = TripadvisorSearchLocation(query="London")
var1 = TripadvisorSearchLocation(query="London")
Executing: TripadvisorSearchHotels(param="foo", geoId="123", checkIn="2024-09-05", checkOut="2024-09-15")