diff --git a/FirebaseVertexAI/Sources/FunctionCalling.swift b/FirebaseVertexAI/Sources/FunctionCalling.swift index 60514a6f5f4..e488debe3be 100644 --- a/FirebaseVertexAI/Sources/FunctionCalling.swift +++ b/FirebaseVertexAI/Sources/FunctionCalling.swift @@ -19,7 +19,7 @@ import Foundation /// This `FunctionDeclaration` is a representation of a block of code that can be used as a ``Tool`` /// by the model and executed by the client. @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) -public struct FunctionDeclaration { +public struct FunctionDeclaration: Equatable { /// The name of the function. let name: String @@ -48,6 +48,22 @@ public struct FunctionDeclaration { nullable: false ) } + + /// Constructs a new `FunctionDeclaration`. + /// + /// - Parameters: + /// - jsonString: A string representing a function declaration in JSON format; see the [REST + /// documentation]( https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/Tool#FunctionDeclaration) + /// for details. + public init(jsonString: String) throws { + guard let jsonData = jsonString.data(using: .utf8) else { + throw DecodingError.dataCorrupted(DecodingError.Context( + codingPath: [], + debugDescription: "Could not parse JSON string as UTF8." + )) + } + self = try JSONDecoder().decode(Self.self, from: jsonData) + } } /// A helper tool that the model may use when generating responses. @@ -146,7 +162,7 @@ public struct ToolConfig { // MARK: - Codable Conformance @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) -extension FunctionDeclaration: Encodable { +extension FunctionDeclaration: Codable { enum CodingKeys: String, CodingKey { case name case description diff --git a/FirebaseVertexAI/Sources/Types/Internal/DataType.swift b/FirebaseVertexAI/Sources/Types/Internal/DataType.swift index f995eacddf2..66cbf0b7d32 100644 --- a/FirebaseVertexAI/Sources/Types/Internal/DataType.swift +++ b/FirebaseVertexAI/Sources/Types/Internal/DataType.swift @@ -37,4 +37,4 @@ enum DataType: String { // MARK: - Codable Conformance -extension DataType: Encodable {} +extension DataType: Codable {} diff --git a/FirebaseVertexAI/Sources/Types/Public/Schema.swift b/FirebaseVertexAI/Sources/Types/Public/Schema.swift index a5fd2cdd0fb..fa456fa67cf 100644 --- a/FirebaseVertexAI/Sources/Types/Public/Schema.swift +++ b/FirebaseVertexAI/Sources/Types/Public/Schema.swift @@ -19,7 +19,7 @@ import Foundation /// These types can be objects, but also primitives and arrays. Represents a select subset of an /// [OpenAPI 3.0 schema object](https://spec.openapis.org/oas/v3.0.3#schema). @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) -public class Schema { +public final class Schema { /// Modifiers describing the expected format of a string `Schema`. @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) public struct StringFormat: EncodableProtoEnum { @@ -319,7 +319,7 @@ public class Schema { // MARK: - Codable Conformance @available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) -extension Schema: Encodable { +extension Schema: Codable { enum CodingKeys: String, CodingKey { case dataType = "type" case format @@ -331,3 +331,15 @@ extension Schema: Encodable { case requiredProperties = "required" } } + +// MARK: - Equatable Conformance + +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) +extension Schema: Equatable { + public static func == (lhs: Schema, rhs: Schema) -> Bool { + return lhs.dataType == rhs.dataType && lhs.format == rhs.format + && lhs.description == rhs.description && lhs.nullable == rhs.nullable + && lhs.enumValues == rhs.enumValues && lhs.items == rhs.items + && lhs.properties == rhs.properties && lhs.requiredProperties == rhs.requiredProperties + } +} diff --git a/FirebaseVertexAI/Tests/Unit/Types/FunctionDeclarationTests.swift b/FirebaseVertexAI/Tests/Unit/Types/FunctionDeclarationTests.swift new file mode 100644 index 00000000000..df87c9dde74 --- /dev/null +++ b/FirebaseVertexAI/Tests/Unit/Types/FunctionDeclarationTests.swift @@ -0,0 +1,48 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import FirebaseVertexAI +import XCTest + +@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *) +final class FunctionDeclarationTests: XCTestCase { + func testFunctionDeclaration_jsonString() throws { + let json = """ + { + "name": "getWeather", + "description": "gets the weather for a requested city", + "parameters": { + "type": "OBJECT", + "properties": { + "city": { + "type": "STRING", + "nullable": false + } + }, + "nullable": false, + "required": ["city"] + } + } + """ + let expectedFunctionDeclaration = FunctionDeclaration( + name: "getWeather", + description: "gets the weather for a requested city", + parameters: ["city": .string()] + ) + + let functionDeclaration = try FunctionDeclaration(jsonString: json) + + XCTAssertEqual(functionDeclaration, expectedFunctionDeclaration) + } +}