From eda816df06957053ebc2baccd16253314bf56aaf Mon Sep 17 00:00:00 2001 From: Reid Chatham Date: Fri, 8 Dec 2023 18:38:02 -0800 Subject: [PATCH 1/7] Update OpenAI.swift --- Sources/OpenAIKit/OpenAI.swift | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/Sources/OpenAIKit/OpenAI.swift b/Sources/OpenAIKit/OpenAI.swift index 6947c9d..881f4b0 100644 --- a/Sources/OpenAIKit/OpenAI.swift +++ b/Sources/OpenAIKit/OpenAI.swift @@ -52,19 +52,10 @@ public final class OpenAI { /// - Parameter b64Data: The `Base64` data itself in `String` form. /// - Returns: A `UIImage` object. public func decodeBase64Image(_ b64Data: String) throws -> UIImage { - do { - guard let data = Data(base64Encoded: b64Data) else { - throw OpenAIError.invalidData - } - - guard let image = UIImage(data: data) else { - throw OpenAIError.invalidData - } - - return image - } catch { + guard let data = Data(base64Encoded: b64Data), let image = UIImage(data: data) else { throw OpenAIError.invalidData } + return image } #endif @@ -73,19 +64,10 @@ public final class OpenAI { /// - Parameter b64Data: The `Base64` data itself in `String` form. /// - Returns: An `NSImage` object. public func decodeBase64Image(_ b64Data: String) throws -> NSImage { - do { - guard let data = Data(base64Encoded: b64Data) else { - throw OpenAIError.invalidData - } - - guard let image = NSImage(data: data) else { - throw OpenAIError.invalidData - } - - return image - } catch { + guard let data = Data(base64Encoded: b64Data), let image = NSImage(data: data) else { throw OpenAIError.invalidData } + return image } #endif @@ -96,7 +78,6 @@ public final class OpenAI { guard let result = URL(string: "https://api.openai.com/v1\(path)") else { throw OpenAIError.invalidUrl } - return result } } From 8a1dc943523e3fd5f272d3c7e78b5e2d29a84b58 Mon Sep 17 00:00:00 2001 From: Reid Chatham Date: Sat, 9 Dec 2023 12:35:26 -0800 Subject: [PATCH 2/7] Update OpenAISource.swift --- .../Utils/OpenAIStreamer/OpenAISource.swift | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift index 6f3b5f0..55aeb63 100644 --- a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift +++ b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift @@ -231,26 +231,18 @@ public extension OpenAISource { let connection = OpenAISource(url: self.url) connection.onMessageCallback = { message in + if message.data != nil, message.data! == "[DONE]" { + continuation.finish() + } + guard let data = message.data?.data(using: .utf8) else { + throw OpenAIError.invalidData + } do { - if message.data != nil, message.data! == "[DONE]" { - continuation.finish() - } - - guard let data = message.data?.data(using: .utf8) else { - throw OpenAIError.invalidData - } let result = try OpenAIKitSession.decodeData(T.self, with: data) continuation.yield(result) } catch { - do { - guard let data = message.data?.data(using: .utf8) else { - throw OpenAIError.invalidData - } - let errorOpenAI = try JSONDecoder().decode(OpenAIErrorResponse.self, from: data) - continuation.finish(throwing: errorOpenAI) - } catch { - continuation.finish(throwing: error) - } + let errorOpenAI = try? JSONDecoder().decode(OpenAIErrorResponse.self, from: data) + continuation.finish(throwing: errorOpenAI ?? error) } } From 3898599426ff02b577d7da99a0aa44603544d59d Mon Sep 17 00:00:00 2001 From: Reid Chatham Date: Sat, 9 Dec 2023 12:55:50 -0800 Subject: [PATCH 3/7] Update OpenAIKitSession.swift --- .../OpenAIKit/Utils/OpenAIKitSession.swift | 58 +++++++++---------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/Sources/OpenAIKit/Utils/OpenAIKitSession.swift b/Sources/OpenAIKit/Utils/OpenAIKitSession.swift index 38012c9..12dadb8 100644 --- a/Sources/OpenAIKit/Utils/OpenAIKitSession.swift +++ b/Sources/OpenAIKit/Utils/OpenAIKitSession.swift @@ -229,47 +229,43 @@ final class OpenAIKitSession { formSubmission: Bool = false ) async throws -> T { guard let apiKey = apiKey else { throw OpenAIError.noApiKey } - - if bodyRequired { - guard let body = body else { throw OpenAIError.noBody } - - if formSubmission { - let formRequest = FormDataHelper(formUrl: url) - - body.forEach { (key, value) in - if let dataValue = value as? FormData { - formRequest.addDataField(named: key, formData: dataValue) - } else { - formRequest.addTextField(named: key, value: "\(value)") - } - } - - let request = formRequest.asURLRequest(apiKey: apiKey) - let data = try await self.asyncData(with: request) - - return try OpenAIKitSession.decodeData(with: data) - } else { - let jsonData = try? JSONSerialization.data(withJSONObject: body) + guard let body = body else { + if !bodyRequired && !formSubmission { // no body req - no form let data = try await self.asyncData( - with: url, method: method, - headers: ["Authorization": "Bearer \(apiKey)"], - body: jsonData + with: url, + method: method, + headers: ["Authorization": "Bearer \(apiKey)"] ) - + return try OpenAIKitSession.decodeData(with: data) } + throw OpenAIError.noBody // no body } - if !bodyRequired && !formSubmission { + if formSubmission { // body required + form sub + let formRequest = FormDataHelper(formUrl: url) + + body.forEach { (key, value) in + if let dataValue = value as? FormData { + formRequest.addDataField(named: key, formData: dataValue) + } else { + formRequest.addTextField(named: key, value: "\(value)") + } + } + + let request = formRequest.asURLRequest(apiKey: apiKey) + let data = try await self.asyncData(with: request) + + return try OpenAIKitSession.decodeData(with: data) + } else { // body required only + let jsonData = try? JSONSerialization.data(withJSONObject: body) let data = try await self.asyncData( - with: url, - method: method, - headers: ["Authorization": "Bearer \(apiKey)"] + with: url, method: method, + headers: ["Authorization": "Bearer \(apiKey)"], + body: jsonData ) return try OpenAIKitSession.decodeData(with: data) } - - throw OpenAIError.noBody } } From 7426fdb49857275c3db96e53880f5c405885fa07 Mon Sep 17 00:00:00 2001 From: Reid Chatham Date: Sat, 9 Dec 2023 13:50:43 -0800 Subject: [PATCH 4/7] Update OpenAISource.swift --- Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift index 55aeb63..f836ca8 100644 --- a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift +++ b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift @@ -231,12 +231,8 @@ public extension OpenAISource { let connection = OpenAISource(url: self.url) connection.onMessageCallback = { message in - if message.data != nil, message.data! == "[DONE]" { - continuation.finish() - } - guard let data = message.data?.data(using: .utf8) else { - throw OpenAIError.invalidData - } + guard let messageData = message.data, messageData != "[DONE]" { continuation.finish() } + let data = Data(messageData.utf8) do { let result = try OpenAIKitSession.decodeData(T.self, with: data) continuation.yield(result) From 7902f5d7c886db4da960d8afdc93deea1de8344f Mon Sep 17 00:00:00 2001 From: Reid Chatham Date: Sat, 9 Dec 2023 14:17:37 -0800 Subject: [PATCH 5/7] Update OpenAISource.swift --- .../Utils/OpenAIStreamer/OpenAISource.swift | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift index f836ca8..fe5a595 100644 --- a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift +++ b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift @@ -231,14 +231,11 @@ public extension OpenAISource { let connection = OpenAISource(url: self.url) connection.onMessageCallback = { message in - guard let messageData = message.data, messageData != "[DONE]" { continuation.finish() } - let data = Data(messageData.utf8) - do { - let result = try OpenAIKitSession.decodeData(T.self, with: data) - continuation.yield(result) - } catch { - let errorOpenAI = try? JSONDecoder().decode(OpenAIErrorResponse.self, from: data) - continuation.finish(throwing: errorOpenAI ?? error) + guard let messageData = message.data, messageData != "[DONE]" else { return continuation.finish() } + do { continuation.yield(try OpenAIKitSession.decodeData(T.self, with: Data(messageData.utf8))) } + catch { + let apiError = try? JSONDecoder().decode(OpenAIErrorResponse.self, from: Data(messageData.utf8)) + continuation.finish(throwing: apiError ?? error) } } From 2e15158defdc5c9a4e0fb5cedf998af8928c2f01 Mon Sep 17 00:00:00 2001 From: Reid Chatham Date: Sat, 9 Dec 2023 14:31:49 -0800 Subject: [PATCH 6/7] OpenAIKitSession.decodeData decodes to OpenAIErrorResponse and throws on failure --- Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift index fe5a595..4c25f63 100644 --- a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift +++ b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift @@ -233,10 +233,7 @@ public extension OpenAISource { connection.onMessageCallback = { message in guard let messageData = message.data, messageData != "[DONE]" else { return continuation.finish() } do { continuation.yield(try OpenAIKitSession.decodeData(T.self, with: Data(messageData.utf8))) } - catch { - let apiError = try? JSONDecoder().decode(OpenAIErrorResponse.self, from: Data(messageData.utf8)) - continuation.finish(throwing: apiError ?? error) - } + catch { continuation.finish(throwing: error) } } continuation.onTermination = { @Sendable _ in From 4e9b0a46db87aaea9788ade75f6b694c41eb8c91 Mon Sep 17 00:00:00 2001 From: Reid Chatham Date: Sat, 9 Dec 2023 14:36:38 -0800 Subject: [PATCH 7/7] return OpenAIError.invalidData when nil data returned --- Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift index 4c25f63..4b19502 100644 --- a/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift +++ b/Sources/OpenAIKit/Utils/OpenAIStreamer/OpenAISource.swift @@ -231,7 +231,8 @@ public extension OpenAISource { let connection = OpenAISource(url: self.url) connection.onMessageCallback = { message in - guard let messageData = message.data, messageData != "[DONE]" else { return continuation.finish() } + guard let messageData = message.data, messageData != "[DONE]" + else { return message.data == nil ? continuation.finish(throwing: OpenAIError.invalidData) : continuation.finish() } do { continuation.yield(try OpenAIKitSession.decodeData(T.self, with: Data(messageData.utf8))) } catch { continuation.finish(throwing: error) } }