Files
PhoneClaw/Packages/InferenceKit/Libraries/MLXLMCommon/Tool/ToolCall.swift
T

58 lines
1.9 KiB
Swift

// Copyright © 2025 Apple Inc.
import Foundation
public struct ToolCall: Hashable, Codable, Sendable {
/// Represents the function details for a tool call
public struct Function: Hashable, Codable, Sendable {
/// The name of the function
public let name: String
/// The arguments passed to the function
public let arguments: [String: JSONValue]
public init(name: String, arguments: [String: any Sendable]) {
self.name = name
self.arguments = arguments.mapValues { JSONValue.from($0) }
}
}
/// The function to be called
public let function: Function
public init(function: Function) {
self.function = function
}
}
extension ToolCall {
public func execute<Input, Output>(with tool: Tool<Input, Output>) async throws -> Output {
// Check that the tool name matches the function name
guard tool.name == function.name else {
throw ToolError.nameMismatch(toolName: tool.name, functionName: function.name)
}
// Convert the JSONValue arguments dictionary to a JSON-encoded Data object
let jsonObject = function.arguments.mapValues { $0.anyValue }
let jsonData = try JSONSerialization.data(withJSONObject: jsonObject)
// Decode the Input type from the JSON data
let input = try JSONDecoder().decode(Input.self, from: jsonData)
// Execute the tool's handler with the decoded input
return try await tool.handler(input)
}
}
// Define Tool-related errors
public enum ToolError: Error, LocalizedError {
case nameMismatch(toolName: String, functionName: String)
public var errorDescription: String? {
switch self {
case .nameMismatch(let toolName, let functionName):
return "Tool name mismatch: expected '\(toolName)' but got '\(functionName)'"
}
}
}