-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Tool
macro
#3
Conversation
d315d3b
to
744df1b
Compare
Convert ClientTests to use SwiftTesting
On the one hand, I love the reduction in boilerplate involved. To do anything meaningful you'll need to connect it to other APIs, include references to database, other API (weather API for example), etc.. all of which you likely have accessible and initialised when you make the llm call. (where you'd assign the closure or tools). So as a user of this API, the other approach has more boiler plate to deal with, but otherwise is much more useable and easier to manage. On the other hand this approach could probably be adapted to methods and just skip the first The parameter and return type creation also likely need a conversion step where they are converted from the Swift type to a JSON type, as Int doesn't exist in json, for example. |
@kylehowells Thanks for sharing your thoughts. That's helpful feedback.
I totally agree. The class WeatherService {
static var `default`: WeatherService = WeatherService()
func getCurrentWeather(latitude: Double, longitude: Double) async throws -> String {
// ...
}
}
enum ToolGetCurrentWeather: Tool {
struct Input: Codable {
let latitude: Double
let longitude: Double
}
typealias Output = String
static var weatherService: WeatherService!
static var schema: [String: Value] {
[
"name": "get_current_weather",
"description": "Gets the current weather for a location",
"parameters": [
"latitude": [
"type": "number"
],
"longitude": [
"type": "number"
]
]
]
}
static func call(_ input: Input) async throws -> Output {
return await WeatherService.default.getCurrentWeather(latitude: input.latitude,
longitude: input.longitude)
}
} I'm also working on a let weatherTool = #createTool(
name: "getWeather",
description: "Get weather for location",
parameters: ["location": ["type": "string"]],
{ (latitude: Double, longitude: Double) async throws -> String in
return await WeatherService.default.getCurrentWeather(latitude: input.latitude,
longitude: input.longitude)
}
)
That's right. This was missing in the first pass, but I've since added this. Custom struct types are dicey, but they should work as expected if they conform to |
Adopting Swift macros currently has a significant impact on compilation times. This should be fixed by a recent PR that allows Swift Package Manager to use a pre-built distribution of swift-syntax. This is scheduled to go out with Swift 6.1, likely in March with the Spring Xcode release. Holding in draft at least until then. |
Closing in favor of #7 |
Related to #1
Expands to: