From b21147f6ca810c056cb6e248f5556301ac5b079a Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Tue, 12 Dec 2023 11:30:51 -0500 Subject: [PATCH] Remove `Codable` conformance for request or response-only types (#34) --- Sources/GoogleAI/CountTokensRequest.swift | 2 +- Sources/GoogleAI/Errors.swift | 24 +++++++---- Sources/GoogleAI/GenerateContentRequest.swift | 2 +- .../GoogleAI/GenerateContentResponse.swift | 41 +++++++++++++++---- Sources/GoogleAI/GenerationConfig.swift | 2 +- Sources/GoogleAI/Safety.swift | 4 +- 6 files changed, 56 insertions(+), 19 deletions(-) diff --git a/Sources/GoogleAI/CountTokensRequest.swift b/Sources/GoogleAI/CountTokensRequest.swift index c02e9a3..348eb0c 100644 --- a/Sources/GoogleAI/CountTokensRequest.swift +++ b/Sources/GoogleAI/CountTokensRequest.swift @@ -33,6 +33,6 @@ extension CountTokensRequest: GenerativeAIRequest { } } -public struct CountTokensResponse: Codable { +public struct CountTokensResponse: Decodable { public let totalTokens: Int } diff --git a/Sources/GoogleAI/Errors.swift b/Sources/GoogleAI/Errors.swift index b3bcbec..0809589 100644 --- a/Sources/GoogleAI/Errors.swift +++ b/Sources/GoogleAI/Errors.swift @@ -14,20 +14,22 @@ import Foundation -struct RPCError: Error, Decodable { +struct RPCError: Error { let httpResponseCode: Int32 let message: String let status: RPCStatus - enum CodingKeys: CodingKey { - case error - } - init(httpResponseCode: Int32, message: String, status: RPCStatus) { self.httpResponseCode = httpResponseCode self.message = message self.status = status } +} + +extension RPCError: Decodable { + enum CodingKeys: CodingKey { + case error + } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -53,10 +55,18 @@ struct RPCError: Error, Decodable { } } -struct ErrorStatus: Codable { +struct ErrorStatus { let code: Int32? let message: String? let status: RPCStatus? +} + +extension ErrorStatus: Decodable { + enum CodingKeys: CodingKey { + case code + case message + case status + } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -70,7 +80,7 @@ struct ErrorStatus: Codable { } } -enum RPCStatus: String, Codable { +enum RPCStatus: String, Decodable { // Not an error; returned on success. case ok = "OK" diff --git a/Sources/GoogleAI/GenerateContentRequest.swift b/Sources/GoogleAI/GenerateContentRequest.swift index 074913a..6629056 100644 --- a/Sources/GoogleAI/GenerateContentRequest.swift +++ b/Sources/GoogleAI/GenerateContentRequest.swift @@ -24,7 +24,7 @@ struct GenerateContentRequest { } extension GenerateContentRequest: Encodable { - private enum CodingKeys: String, CodingKey { + enum CodingKeys: String, CodingKey { case contents case generationConfig case safetySettings diff --git a/Sources/GoogleAI/GenerateContentResponse.swift b/Sources/GoogleAI/GenerateContentResponse.swift index 3f5d29e..d9ac4e8 100644 --- a/Sources/GoogleAI/GenerateContentResponse.swift +++ b/Sources/GoogleAI/GenerateContentResponse.swift @@ -14,7 +14,7 @@ import Foundation -public struct GenerateContentResponse: Codable { +public struct GenerateContentResponse { public let candidates: [CandidateResponse] public let promptFeedback: PromptFeedback? @@ -36,6 +36,13 @@ public struct GenerateContentResponse: Codable { self.candidates = candidates self.promptFeedback = promptFeedback } +} + +extension GenerateContentResponse: Decodable { + enum CodingKeys: CodingKey { + case candidates + case promptFeedback + } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -62,7 +69,7 @@ public struct GenerateContentResponse: Codable { } } -public struct CandidateResponse: Codable { +public struct CandidateResponse { public let content: ModelContent public let safetyRatings: [SafetyRating] @@ -78,6 +85,16 @@ public struct CandidateResponse: Codable { self.finishReason = finishReason self.citationMetadata = citationMetadata } +} + +extension CandidateResponse: Decodable { + enum CodingKeys: CodingKey { + case content + case safetyRatings + case finishReason + case finishMessage + case citationMetadata + } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -117,18 +134,18 @@ public struct CandidateResponse: Codable { } /// A collection of source attributions for a piece of content. -public struct CitationMetadata: Codable { +public struct CitationMetadata: Decodable { public let citationSources: [Citation] } -public struct Citation: Codable { +public struct Citation: Decodable { public let startIndex: Int public let endIndex: Int public let uri: String public let license: String } -public enum FinishReason: String, Codable { +public enum FinishReason: String { case unknown = "FINISH_REASON_UNKNOWN" case unspecified = "FINISH_REASON_UNSPECIFIED" @@ -145,7 +162,9 @@ public enum FinishReason: String, Codable { case safety = "SAFETY" case recitation = "RECITATION" case other = "OTHER" +} +extension FinishReason: Decodable { /// Do not explicitly use. Initializer required for Decodable conformance. public init(from decoder: Decoder) throws { let value = try decoder.singleValueContainer().decode(String.self) @@ -160,8 +179,8 @@ public enum FinishReason: String, Codable { } } -public struct PromptFeedback: Codable { - public enum BlockReason: String, Codable { +public struct PromptFeedback { + public enum BlockReason: String, Decodable { case unknown = "UNKNOWN" case unspecified = "BLOCK_REASON_UNSPECIFIED" case safety = "SAFETY" @@ -189,7 +208,15 @@ public struct PromptFeedback: Codable { self.blockReason = blockReason self.safetyRatings = safetyRatings } +} +extension PromptFeedback: Decodable { + enum CodingKeys: CodingKey { + case blockReason + case safetyRatings + } + + /// Do not explicitly use. Initializer required for Decodable conformance. public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) blockReason = try container.decodeIfPresent( diff --git a/Sources/GoogleAI/GenerationConfig.swift b/Sources/GoogleAI/GenerationConfig.swift index ba8cc3c..c417e59 100644 --- a/Sources/GoogleAI/GenerationConfig.swift +++ b/Sources/GoogleAI/GenerationConfig.swift @@ -16,7 +16,7 @@ import Foundation /// A struct defining model parameters to be used when sending generative AI /// requests to the backend model. -public struct GenerationConfig: Codable { +public struct GenerationConfig: Encodable { /// A parameter controlling the degree of randomness in token selection. A /// temperature of zero is deterministic, always choosing the /// highest-probability response. Typical values are between 0 and 1 diff --git a/Sources/GoogleAI/Safety.swift b/Sources/GoogleAI/Safety.swift index 36ac8cf..1ec3f13 100644 --- a/Sources/GoogleAI/Safety.swift +++ b/Sources/GoogleAI/Safety.swift @@ -17,7 +17,7 @@ import Foundation /// A type defining potentially harmful media categories and their model-assigned ratings. A value /// of this type may be assigned to a category for every model-generated response, not just /// responses that exceed a certain threshold. -public struct SafetyRating: Codable, Equatable { +public struct SafetyRating: Decodable, Equatable { /// The category describing the potential harm a piece of content may pose. See /// ``SafetySetting.HarmCategory`` for a list of possible values. public let category: SafetySetting.HarmCategory @@ -74,7 +74,7 @@ public struct SafetyRating: Codable, Equatable { } /// Safety feedback for an entire request. -public struct SafetyFeedback: Codable { +public struct SafetyFeedback: Decodable { /// Safety rating evaluated from content. public let rating: SafetyRating