## Tool Calling

LLMs can't access real-time data or perform actions. Tools let the model invoke external functions during generation.

## The Type Transformation Journey

```
╔════════════════════════════════════════════════════════╗
║  YOUR PLAIN TYPES                                      ║
╠════════════════════════════════════════════════════════╣
║  // sourcery: toolGenerable                            ║
║  struct WeatherInfoArguments: Sendable {               ║
║      var city: String                                  ║
║  }                                                     ║
║                                                        ║
║  // sourcery: toolGenerable                            ║
║  struct WeatherInfoResult: Sendable {                  ║
║      var temperature: Int                              ║
║  }                                                     ║
║                                                        ║
║  // sourcery: inferenceToolAdapter                     ║
║  struct GetWeatherTool: InferenceTool {                ║
║      var name = "Get weather"                          ║
║      var description = "..."                           ║
║      typealias Arguments = WeatherInfoArguments        ║
║      typealias Output = WeatherInfoResult              ║
║                                                        ║
║      func call(arguments: Arguments) async throws      ║
║          -> Output { /* your impl */ }                 ║
║  }                                                     ║
║                                                        ║
║  Clean. No Foundation Models dependencies.             ║
╚════════════════════════════════════════════════════════╝
                        ↓
                [Sourcery runs]
                        ↓
╔════════════════════════════════════════════════════════╗
║  GENERATED: ToolGenerableWeatherInfoArguments          ║
╠════════════════════════════════════════════════════════╣
║  @Generable(description: "...")                        ║
║  struct ToolGenerableWeatherInfoArguments: Sendable {  ║
║      @Guide(description: "...")                        ║
║      var city: String                                  ║
║  }                                                     ║
║                                                        ║
║  Foundation Models compatible                          ║
╚════════════════════════════════════════════════════════╝
                        ↓
╔════════════════════════════════════════════════════════╗
║  GENERATED: ToolGenerableWeatherInfoResult             ║
╠════════════════════════════════════════════════════════╣
║  @Generable(description: "...")                        ║
║  struct ToolGenerableWeatherInfoResult: Sendable {     ║
║      @Guide(description: "...")                        ║
║      var temperature: Int                              ║
║  }                                                     ║
║                                                        ║
║  Foundation Models compatible                          ║
╚════════════════════════════════════════════════════════╝
                        ↓
╔════════════════════════════════════════════════════════╗
║  GENERATED: FoundationModelsGetWeatherTool             ║
╠════════════════════════════════════════════════════════╣
║  struct FoundationModelsGetWeatherTool: Tool {         ║
║      let wrapped: GetWeatherTool                       ║
║      typealias Arguments =                             ║
║          ToolGenerableWeatherInfoArguments             ║
║      typealias Output =                                ║
║          ToolGenerableWeatherInfoResult                ║
║                                                        ║
║      func call(arguments: Arguments) async throws      ║
║          -> Output {                                   ║
║          // Convert ToolGenerable → Plain              ║
║          let plainArgs = WeatherInfoArguments(...)     ║
║          // Call your tool                             ║
║          let plainResult = wrapped.call(plainArgs)     ║
║          // Convert Plain → ToolGenerable              ║
║          return ToolGenerableWeatherInfoResult(...)    ║
║      }                                                 ║
║  }                                                     ║
║                                                        ║
║  Adapter wraps your tool for Foundation Models         ║
╚════════════════════════════════════════════════════════╝
                        ↓
╔════════════════════════════════════════════════════════╗
║  GENERATED: Extension                                  ║
╠════════════════════════════════════════════════════════╣
║  extension GetWeatherTool:                             ║
║      FoundationModelsConvertibleTool {                 ║
║                                                        ║
║      func toFoundationModelsTool() -> any Tool {       ║
║          return FoundationModelsGetWeatherTool(        ║
║              wrapped: self                             ║
║          )                                             ║
║      }                                                 ║
║  }                                                     ║
║                                                        ║
║  Your tool can now convert to FM Tool                  ║
╚════════════════════════════════════════════════════════╝
```

## What You Actually Write

```swift
// 1. Define your argument type
// sourcery: toolGenerable
// sourcery: toolGenerableDescription = "Weather information arguments"
public struct WeatherInfoArguments: Sendable {
    // sourcery: guideDescription = "The name of the city"
    public var city: String
}

// 2. Define your output type
// sourcery: toolGenerable
// sourcery: toolGenerableDescription = "Weather information result"
public struct WeatherInfoResult: Sendable {
    // sourcery: guideDescription = "The temperature"
    public var temperature: Int
}

// 3. Define your tool
// sourcery: inferenceToolAdapter
// sourcery: toolArgumentsType = "WeatherInfoArguments"
// sourcery: toolOutputType = "WeatherInfoResult"
public struct GetWeatherTool: InferenceTool {
    public var name = "Get weather"
    public var description = "Retrieve weather for a city"
    
    public typealias Arguments = WeatherInfoArguments
    public typealias Output = WeatherInfoResult
    
    public func call(arguments: Arguments) async throws -> Output {
        // Your implementation
        let data = await weatherAPI.fetch(arguments.city)
        return WeatherInfoResult(temperature: data.temp)
    }
}
```

## Tool Selection Logic

```
LLM decision process:

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Can answer directly?       ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
         │
    ┌────┴────┐
   YES       NO
    │         │
    │         ▼
    │    ┏━━━━━━━━━━━━━━━━━━━━━━┓
    │    ┃ Need external data?  ┃
    │    ┗━━━━━━━━━━━━━━━━━━━━━━┛
    │              │
    │         ┌────┴────┐
    │        YES       NO
    │         │         │
    │         ▼         │
    │   ┏━━━━━━━━━━━━━┓│
    │   ┃ Select tool ┃│
    │   ┗━━━━━━━━━━━━━┛│
    │         │         │
    ▼         ▼         ▼
[Direct] [Use Tool] [Direct]
```

## Decision Guide

```
╔═══════════════════════════╦════════════════════════════╗
║ Use Tools When            ║ Don't Use When             ║
╠═══════════════════════════╬════════════════════════════╣
║ Need real-time data       ║ Model can answer directly  ║
║ External API calls needed ║ No external data needed    ║
║ Perform calculations      ║ Performance critical       ║
║ Access databases/files    ║ Added latency unacceptable ║
║ Business logic required   ║ Simple generation          ║
╚═══════════════════════════╩════════════════════════════╝
```
