Tools and Functions
Last modified: 04 October 2024The Vapi4k DSL allows you to assign tools and functions to assistants, which enables an LLM to perform tasks and calculations.
Tools
The tools{}
lambda can contain serviceTool()
, manualTool()
, externalTool()
, and transferTool()
calls.
ServiceTool
The serviceTool()
argument can be either an object instance or a reference to a Kotlin singleton object. The return value and method parameters are limited to types: String
, Int
, Double
, Boolean
, and Unit
.
If you want access to the requestContext value of the tool call in the serviceTool implementation, add a parameter of type RequestContext
to the method signature. It will be automatically injected along with the LLM arguments.
fun CommonModelProperties.serviceToolExample() {
tools {
serviceTool(AddTwoNumbers())
serviceTool(MultiplyTwoNumbers())
serviceTool(AbsoluteValue)
}
}
Here are some examples of serviceTool implementations.
In the case of a non-annotated function, only a single method is allowed in the object.
Non-annotated Function
class AddTwoNumbers {
fun addTwoNumbers(
a: Int,
b: Int,
requestContext: RequestContext, // This is optional
): Int {
return a + b
}
}
The @ToolCall
and @Param
annotations are used to express intent to the LLM. The @ToolCall
annotation describes when a function or serviceTool should be called, and the @Param
annotation describes the parameters of the function or serviceTool. If a function or serviceTool is not annotated, the LLM will infer when to invoke the function based on the function name and the arguments from the parameter names.
Multiple methods can have @ToolCall
annotations. In addition, other non-annotated methods in the object are also allowed.
Annotated Function
class MultiplyTwoNumbers {
@ToolCall("Multiply two numbers")
fun add(
@Param("First number to multiply")
a: Int,
@Param("Second number to Multiply")
b: Int,
): Int {
return a + b
}
}
This is an example of using a Kotlin singleton object.
Singleton Object Function
object AbsoluteValue {
@ToolCall("Absolute value of a number")
fun absolute(
@Param("Number")
a: Int,
): Int {
return a.absoluteValue
}
}
A tool{}
implementation object can also inherit from ToolCallService()
.
Singleton Object Function
class WeatherLookupService : ToolCallService() {
@ToolCall("Look up the weather for a city")
fun getWeatherByCity(
city: String,
state: String,
) = "The weather in city $city and state $state is windy"
@ToolCall("Look up the weather for a zip code")
fun getWeatherByZipCode(zipCode: String) = "The weather in zip code $zipCode is rainy"
override fun onToolCallComplete(
requestContext: RequestContext,
result: String,
): List<ToolMessageCompleteImpl> =
requestCompleteMessages {
condition("city" eq "Chicago", "state" eq "Illinois") {
requestCompleteMessage {
content = "The Chicago weather lookup override request complete"
}
}
requestCompleteMessage {
role = ToolMessageRoleType.ASSISTANT
content = "The generic weather lookup override request complete"
}
}
}
ManualTool
A manualTool()
describes a function whose implementation is within the Vapi4k DSL. The parameters are manually extracted from the args
JsonElement, which is the JSON object included in the LLM request. A manualTool()
is not associated with a specific Kotlin object.
fun CommonModelProperties.manualToolExample() {
tools {
manualTool {
name = "manualWeatherLookup"
description = "Look up the weather for a city and state"
parameters {
parameter {
name = "city"
description = "The city to look up"
}
parameter {
name = "state"
description = "The state to look up"
}
}
requestStartMessage {
content = "This is the manual weather lookup start message"
}
onInvoke { args: JsonElement ->
val city = args.stringValue("city")
val state = args.stringValue("state")
result = "The weather in $city, $state is ${listOf("sunny", "cloudy", "rainy").random()}"
requestCompleteMessages {
requestCompleteMessage {
content = "This is the manual weather lookup complete message"
}
}
requestFailedMessages {
requestFailedMessage {
content = "This is the manual weather lookup failed message"
}
}
}
}
}
}
ExternalTool
An externalTool()
describes a function executed by a REST endpoint at a specified server.
fun CommonModelProperties.externalToolExample() {
tools {
externalTool {
name = "manualWeatherLookup"
description = "Look up the weather for a city and state"
parameters {
parameter {
name = "city"
description = "The city to look up"
}
parameter {
name = "state"
description = "The state to look up"
}
}
server {
url = "https://your_endpoint.com/weather"
secret = "456"
timeoutSeconds = 5
}
requestStartMessage {
content = "This is the manual weather lookup start message"
}
requestCompleteMessage {
content = "This is the manual weather lookup complete message"
}
requestFailedMessage {
content = "This is the manual weather lookup failed message"
}
}
}
}
TransferTool
A transferTool{}
describes a tool that transfers a user to an assistant or a phone/SIP number.
fun CommonModelProperties.assistantDestinationExample() {
tools {
transferTool {
assistantDestination {
assistantName = "assistant1"
transferMode = AssistantTransferMode.ROLLING_HISTORY
message = "This is the assistant destination message"
description = "Transfer the call to an assistant"
}
}
}
}
fun CommonModelProperties.numberDestinationExample() {
tools {
transferTool {
numberDestination {
number = "+14155551212"
message = "This is the number destination message"
description = "Transfer the call to a phone number"
}
}
}
}
Functions
The functions{}
lambda contains function()
calls. The function()
argument is the same as serviceTool()
calls.
Function Declaration
fun CommonModelProperties.functionExample() {
functions {
function(AddTwoNumbers())
function(MultiplyTwoNumbers())
function(AbsoluteValue)
}
}