starlet/tool
Tool definitions and dispatch helpers for function calling.
Defining Tools
import gleam/json
import starlet/tool
let weather_tool =
tool.function(
name: "get_weather",
description: "Get current weather for a city",
parameters: json.object([
#("type", json.string("object")),
#("properties", json.object([
#("city", json.object([#("type", json.string("string"))])),
])),
]),
)
Handling Tool Calls
let city_decoder = {
use city <- decode.field("city", decode.string)
decode.success(city)
}
let dispatcher = tool.dispatch([
tool.handler("get_weather", city_decoder, fn(city) {
let temp = case city {
"Tokyo" -> 18
_ -> 22
}
Ok(json.object([#("temp", json.int(temp))]))
}),
])
Types
A tool invocation from the model’s response.
The arguments field contains the parsed JSON arguments as a Dynamic value.
pub type Call {
Call(id: String, name: String, arguments: dynamic.Dynamic)
}
Constructors
-
Call(id: String, name: String, arguments: dynamic.Dynamic)
A function that handles a tool call and returns a result.
pub type Handler =
fn(Call) -> Result(ToolResult, ToolError)
Errors that can occur during tool execution.
pub type ToolError {
NotFound(name: String)
InvalidArguments(message: String)
ExecutionFailed(message: String)
}
Constructors
-
NotFound(name: String) -
InvalidArguments(message: String) -
ExecutionFailed(message: String)
Values
pub fn dispatch(
handlers: List(
#(String, fn(Call) -> Result(ToolResult, ToolError)),
),
) -> fn(Call) -> Result(ToolResult, ToolError)
Create a dispatcher that routes calls to the right handler by name.
pub fn dynamic_handler(
name: String,
run: fn(dynamic.Dynamic) -> Result(json.Json, ToolError),
) -> #(String, fn(Call) -> Result(ToolResult, ToolError))
Create a handler tuple from name and a function that receives Dynamic arguments.
For most cases, prefer handler which provides automatic argument decoding.
pub fn error(call: Call, message: String) -> ToolResult
Create an error result (encoded as JSON with error message).
pub fn function(
name name: String,
description description: String,
parameters parameters: json.Json,
) -> Definition
Create a function tool definition.
pub fn handler(
name: String,
decoder: decode.Decoder(a),
run: fn(a) -> Result(json.Json, ToolError),
) -> #(String, fn(Call) -> Result(ToolResult, ToolError))
Create a handler tuple that automatically decodes arguments to a typed value.
Example:
let decoder = {
use city <- decode.field("city", decode.string)
decode.success(city)
}
let #(name, run) =
tool.handler("get_weather", decoder, fn(city) {
Ok(json.string("Weather in " <> city))
})
pub fn success(call: Call, output: json.Json) -> ToolResult
Create a successful tool result from a call.