Skip to content
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

[Vertex AI] Remove ImageConversionError from public API #13735

Merged
merged 2 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions FirebaseVertexAI/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
is now optional (`Int?`); it may be `null` in cases such as when a
`GenerateContentRequest` contains only images or other non-text content.
(#13721)
- [changed] **Breaking Change**: The `ImageConversionError` enum is no longer
public; image conversion errors are still reported as
`GenerateContentError.promptImageContentError`. (#13735)
- [changed] The default request timeout is now 180 seconds instead of the
platform-default value of 60 seconds for a `URLRequest`; this timeout may
still be customized in `RequestOptions`. (#13722)
Expand Down
6 changes: 3 additions & 3 deletions FirebaseVertexAI/Sources/GenerateContentError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import Foundation
/// Errors that occur when generating content from a model.
@available(iOS 15.0, macOS 11.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
public enum GenerateContentError: Error {
/// An error occurred when constructing the prompt. Examine the related error for details.
case promptImageContentError(underlying: ImageConversionError)

/// An internal error occurred. See the underlying error for more context.
case internalError(underlying: Error)

/// An error occurred when constructing the prompt. Examine the related error for details.
case promptImageContentError(underlying: Error)

/// A prompt was blocked. See the response's `promptFeedback.blockReason` for more information.
case promptBlocked(response: GenerateContentResponse)

Expand Down
28 changes: 7 additions & 21 deletions FirebaseVertexAI/Sources/PartsRepresentable+Image.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,15 @@ private let imageCompressionQuality: CGFloat = 0.8
/// An enum describing failures that can occur when converting image types to model content data.
/// For some image types like `CIImage`, creating valid model content requires creating a JPEG
/// representation of the image that may not yet exist, which may be computationally expensive.
public enum ImageConversionError: Error {
/// The image that could not be converted.
public enum SourceImage {
#if canImport(UIKit)
case uiImage(UIImage)
#elseif canImport(AppKit)
case nsImage(NSImage)
#endif // canImport(UIKit)
case cgImage(CGImage)
#if canImport(CoreImage)
case ciImage(CIImage)
#endif // canImport(CoreImage)
}

enum ImageConversionError: Error {
/// The image (the receiver of the call `toModelContentParts()`) was invalid.
case invalidUnderlyingImage

/// A valid image destination could not be allocated.
case couldNotAllocateDestination

/// JPEG image data conversion failed, accompanied by the original image, which may be an
/// instance of `NSImage`, `UIImage`, `CGImage`, or `CIImage`.
case couldNotConvertToJPEG(SourceImage)
/// JPEG image data conversion failed.
case couldNotConvertToJPEG
}

#if canImport(UIKit)
Expand All @@ -55,7 +41,7 @@ public enum ImageConversionError: Error {
extension UIImage: ThrowingPartsRepresentable {
public func tryPartsValue() throws -> [ModelContent.Part] {
guard let data = jpegData(compressionQuality: imageCompressionQuality) else {
throw ImageConversionError.couldNotConvertToJPEG(.uiImage(self))
throw ImageConversionError.couldNotConvertToJPEG
}
return [ModelContent.Part.inlineData(mimetype: "image/jpeg", data)]
}
Expand All @@ -72,7 +58,7 @@ public enum ImageConversionError: Error {
let bmp = NSBitmapImageRep(cgImage: cgImage)
guard let data = bmp.representation(using: .jpeg, properties: [.compressionFactor: 0.8])
else {
throw ImageConversionError.couldNotConvertToJPEG(.nsImage(self))
throw ImageConversionError.couldNotConvertToJPEG
}
return [ModelContent.Part.inlineData(mimetype: "image/jpeg", data)]
}
Expand All @@ -97,7 +83,7 @@ public enum ImageConversionError: Error {
if CGImageDestinationFinalize(imageDestination) {
return [.inlineData(mimetype: "image/jpeg", output as Data)]
}
throw ImageConversionError.couldNotConvertToJPEG(.cgImage(self))
throw ImageConversionError.couldNotConvertToJPEG
}
}
#endif // !os(watchOS)
Expand All @@ -118,7 +104,7 @@ public enum ImageConversionError: Error {
if let jpegData = jpegData {
return [.inlineData(mimetype: "image/jpeg", jpegData)]
}
throw ImageConversionError.couldNotConvertToJPEG(.ciImage(self))
throw ImageConversionError.couldNotConvertToJPEG
}
}
#endif // canImport(CoreImage)
41 changes: 12 additions & 29 deletions FirebaseVertexAI/Tests/Unit/PartsRepresentableTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// limitations under the License.

import CoreGraphics
import FirebaseVertexAI
import XCTest
#if canImport(UIKit)
import UIKit
Expand All @@ -24,6 +23,8 @@ import XCTest
import CoreImage
#endif // canImport(CoreImage)

@testable import FirebaseVertexAI

@available(iOS 15.0, macOS 11.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
final class PartsRepresentableTests: XCTestCase {
#if !os(watchOS)
Expand Down Expand Up @@ -61,22 +62,13 @@ final class PartsRepresentableTests: XCTestCase {
do {
_ = try image.tryPartsValue()
XCTFail("Expected model content from invalid image to error")
} catch {
guard let imageError = (error as? ImageConversionError) else {
XCTFail("Got unexpected error type: \(error)")
return
}
switch imageError {
case let .couldNotConvertToJPEG(source):
guard case let .ciImage(ciImage) = source else {
XCTFail("Unexpected image source: \(source)")
return
}
XCTAssertEqual(ciImage, image)
default:
XCTFail("Expected image conversion error, got \(imageError) instead")
} catch let imageError as ImageConversionError {
guard case .couldNotConvertToJPEG = imageError else {
XCTFail("Expected JPEG conversion error, got \(imageError) instead.")
return
}
} catch {
XCTFail("Got unexpected error type: \(error)")
}
}
#endif // canImport(CoreImage)
Expand All @@ -87,22 +79,13 @@ final class PartsRepresentableTests: XCTestCase {
do {
_ = try image.tryPartsValue()
XCTFail("Expected model content from invalid image to error")
} catch {
guard let imageError = (error as? ImageConversionError) else {
XCTFail("Got unexpected error type: \(error)")
return
}
switch imageError {
case let .couldNotConvertToJPEG(source):
guard case let .uiImage(uiImage) = source else {
XCTFail("Unexpected image source: \(source)")
return
}
XCTAssertEqual(uiImage, image)
default:
XCTFail("Expected image conversion error, got \(imageError) instead")
} catch let imageError as ImageConversionError {
guard case .couldNotConvertToJPEG = imageError else {
XCTFail("Expected JPEG conversion error, got \(imageError) instead.")
return
}
} catch {
XCTFail("Got unexpected error type: \(error)")
}
}

Expand Down
Loading