Tool

A function the model can call, with a name, a description, and a parameter schema.

A tool is a name, a description, a schema for its arguments, and a closure that runs when the model calls it. The description isn't decoration. It's the only thing the model reads when deciding whether this tool applies, so it's worth as much care as the code.

The loop in generateText and streamText executes tools for you and feeds their results back to the model. You only write the closure.

Modifiers on a tool change how the loop treats it. .idempotent() marks a tool as safe to call again with the same arguments, which lets compaction drop its result knowing it can be recovered.

let weather = Tool(
  name: "get_weather",
  description: "Current conditions for a city.",
  parameters: .object(["city": .string(description: "City name")])
) { args, _ in
  let city = args["city"]?.stringValue ?? "London"
  return .string(try await fetchWeather(city))
}.idempotent()

Declaration

public struct Tool

Defined in Sources/AI/Core/Tool.swift.

Initializers

init(
    name: String,
    description: String,
    parameters: JSONValue,
    inputExamples: [JSONValue] = [],
    needsApproval: Bool = false,
    execute: @escaping @Sendable (JSONValue, ToolExecutionOptions) async throws -> JSONValue
)
init(
    name: String,
    description: String,
    parameters: JSONValue,
    inputExamples: [JSONValue] = [],
    needsApproval: Bool = false,
    execute: @escaping @Sendable (JSONValue) async throws -> JSONValue
)
init(
    name: String,
    description: String,
    parameters: JSONValue,
    inputExamples: [JSONValue] = [],
    needsApproval: @escaping @Sendable (JSONValue) async -> Bool,
    execute: @escaping @Sendable (JSONValue) async throws -> JSONValue
)
init(
    name: String,
    description: String,
    parameters: JSONValue,
    inputExamples: [JSONValue] = []
)

Properties

PropertyTypeDefault
let nameString
var descriptionString
let parametersJSONValue
var inputExamples[JSONValue][]
var contextSchemaSchema?
var isDynamicBoolfalse
var isIdempotentBoolfalse
var loadingToolLoading.none
var describeWithContext(@Sendable (JSONValue?) -> String)?
var modelOutput(@Sendable (JSONValue) -> [ContentPart]?)?nil
var hasExecutorBool { run !`nil

Methods

func toModelOutput(
    _ output: JSONValue
) -> [ContentPart]?
func needsApproval(
    _ arguments: JSONValue
) async -> Bool
func description(
    context: JSONValue?
) -> String
func resolvingDescription(
    _ description: String
) -> any AIToolProtocol
func execute(
    _ arguments: JSONValue
) async throws -> JSONValue
func execute(
    _ arguments: JSONValue,
    options: ToolExecutionOptions
) async throws -> JSONValue
func withContextSchema(
    _ schema: Schema
) -> Tool
func idempotent(
    _ isIdempotent: Bool = true
) -> Tool
func describing(
    _ describe: @escaping @Sendable (JSONValue?) -> String
) -> Tool
func loading(
    _ loading: ToolLoading
) -> Tool

See also