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] Add FirebaseVertexAIPreview SPM target for preview APIs #14336

Draft
wants to merge 39 commits into
base: vertex-imagen
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d368abf
[Vertex AI] Add ImageGenerationInstance for input to predict call (#1…
andrewheard Dec 3, 2024
cafca9b
[Vertex AI] Add ImageGenerationParameters for input to predict call (…
andrewheard Dec 3, 2024
24f81c3
[Vertex AI] Add ImageGenerationResponse for decoding PredictResponse …
andrewheard Dec 6, 2024
c2888bd
[Vertex AI] Make `ImageGenerationResponse` generic and add image type…
andrewheard Dec 6, 2024
d1ea5fa
[Vertex AI] Add `ImageGenerationRequest` for Imagen (#14225)
andrewheard Dec 6, 2024
012b158
[Vertex AI] Add `ImagenModel` with `generateImages` functions (#14226)
andrewheard Dec 7, 2024
36a76e2
[Vertex AI] Run Imagen integration tests on cron schedule only (#14231)
andrewheard Dec 7, 2024
c5472fc
[Vertex AI] Add `ImagenGenerationConfig` to `generateImages()` (#14234)
andrewheard Dec 9, 2024
c986629
[Vertex AI] Add `ImagenSafetySettings` type and param (#14237)
andrewheard Dec 10, 2024
1de7f6f
[Vertex AI] Replace `ImagenImage` protocol with `_ImagenImage` struct…
andrewheard Dec 12, 2024
53d43d8
[Vertex AI] Refactor `ImagenSafetySettings` (#14307)
andrewheard Jan 7, 2025
527d4af
[Vertex AI] Add `ImagenModelConfig` for model-level config params (#1…
andrewheard Jan 7, 2025
a3a026a
[Vertex AI] Rename `ImageGenerationResponse` to `ImagenGenerationResp…
andrewheard Jan 8, 2025
d5c8b32
[Vertex AI] Add FirebaseVertexAIPreview SPM target for preview APIs
andrewheard Jan 10, 2025
dbbfb38
[Vertex AI] Make `ImagenImageRepresentable` internal (#14341)
andrewheard Jan 13, 2025
bb7dab5
[Vertex AI] Move `ImagenModelConfig` params to `ImagenGenerationConfi…
andrewheard Jan 14, 2025
6dd2c30
Set package name to `Firebase` in podspec to match `Package.swift`
andrewheard Jan 24, 2025
3e7a3b8
Merge branch 'vertex-imagen' into ah/vertex-imagen-preview-2
andrewheard Jan 24, 2025
4876a0e
Update `createImagenModel` signature
andrewheard Jan 24, 2025
4ac9019
Remove usage of deprecated Python `import sre_compile`
andrewheard Jan 27, 2025
4bf3b54
Fix Firestore import ordering
andrewheard Jan 27, 2025
122d876
[Vertex AI] Add ImageGenerationInstance for input to predict call (#1…
andrewheard Dec 3, 2024
06ef96f
[Vertex AI] Add ImageGenerationParameters for input to predict call (…
andrewheard Dec 3, 2024
c53ee47
[Vertex AI] Add ImageGenerationResponse for decoding PredictResponse …
andrewheard Dec 6, 2024
3a04d77
[Vertex AI] Make `ImageGenerationResponse` generic and add image type…
andrewheard Dec 6, 2024
d7e960c
[Vertex AI] Add `ImageGenerationRequest` for Imagen (#14225)
andrewheard Dec 6, 2024
fdfaea2
[Vertex AI] Add `ImagenModel` with `generateImages` functions (#14226)
andrewheard Dec 7, 2024
36d608e
[Vertex AI] Run Imagen integration tests on cron schedule only (#14231)
andrewheard Dec 7, 2024
2cd3110
[Vertex AI] Add `ImagenGenerationConfig` to `generateImages()` (#14234)
andrewheard Dec 9, 2024
0d50ac3
[Vertex AI] Add `ImagenSafetySettings` type and param (#14237)
andrewheard Dec 10, 2024
58fd515
[Vertex AI] Replace `ImagenImage` protocol with `_ImagenImage` struct…
andrewheard Dec 12, 2024
199aafd
[Vertex AI] Refactor `ImagenSafetySettings` (#14307)
andrewheard Jan 7, 2025
bc5bd82
[Vertex AI] Add `ImagenModelConfig` for model-level config params (#1…
andrewheard Jan 7, 2025
2294db6
[Vertex AI] Rename `ImageGenerationResponse` to `ImagenGenerationResp…
andrewheard Jan 8, 2025
362a01f
[Vertex AI] Make `ImagenImageRepresentable` internal (#14341)
andrewheard Jan 13, 2025
d0e2014
[Vertex AI] Move `ImagenModelConfig` params to `ImagenGenerationConfi…
andrewheard Jan 14, 2025
fa02c07
Merge branch 'vertex-imagen' into ah/vertex-imagen-preview-2
andrewheard Jan 27, 2025
9789b85
Fix Firestore import
andrewheard Jan 27, 2025
be5c048
Exclude VertexAI+Preview.swift in podspec
andrewheard Jan 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/vertexai.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
schedule:
# Run every day at 11pm (PST) - cron uses UTC times
- cron: '0 7 * * *'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
Expand Down Expand Up @@ -102,6 +103,7 @@ jobs:
needs: spm-package-resolved
env:
TEST_RUNNER_FIRAAppCheckDebugToken: ${{ secrets.VERTEXAI_INTEGRATION_FAC_DEBUG_TOKEN }}
TEST_RUNNER_VTXIntegrationImagen: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }}
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
secrets_passphrase: ${{ secrets.GHASecretsGPGPassphrase1 }}
steps:
Expand Down
7 changes: 7 additions & 0 deletions FirebaseVertexAI.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ Firebase SDK.
s.source_files = [
'FirebaseVertexAI/Sources/**/*.swift',
]
s.exclude_files = [
'FirebaseVertexAI/Sources/VertexAI+Preview.swift',
]

s.swift_version = '5.9'

Expand All @@ -49,6 +52,10 @@ Firebase SDK.
s.dependency 'FirebaseCore', '~> 11.8.0'
s.dependency 'FirebaseCoreExtension', '~> 11.8.0'

s.pod_target_xcconfig = {
'OTHER_SWIFT_FLAGS' => '-package-name Firebase'
}

s.test_spec 'unit' do |unit_tests|
unit_tests_dir = 'FirebaseVertexAI/Tests/Unit/'
unit_tests.scheme = { :code_coverage => true }
Expand Down
15 changes: 14 additions & 1 deletion FirebaseVertexAI/Sources/GenerationConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,17 @@ public struct GenerationConfig {
// MARK: - Codable Conformances

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension GenerationConfig: Encodable {}
extension GenerationConfig: Encodable {
enum CodingKeys: String, CodingKey {
case temperature
case topP
case topK
case candidateCount
case maxOutputTokens
case presencePenalty
case frequencyPenalty
case stopSequences
case responseMIMEType = "responseMimeType"
case responseSchema
}
}
3 changes: 3 additions & 0 deletions FirebaseVertexAI/Sources/GenerativeAIRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ public struct RequestOptions {
self.timeout = timeout
}
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension RequestOptions: Equatable {}
1 change: 0 additions & 1 deletion FirebaseVertexAI/Sources/GenerativeAIService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ struct GenerativeAIService {
}

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
urlRequest.httpBody = try encoder.encode(request)
urlRequest.timeoutInterval = request.options.timeout

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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.

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
struct ImageGenerationInstance {
let prompt: String
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImageGenerationInstance: Equatable {}

// MARK: - Codable Conformance

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImageGenerationInstance: Encodable {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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 Foundation

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
struct ImageGenerationOutputOptions {
let mimeType: String
let compressionQuality: Int?
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImageGenerationOutputOptions: Equatable {}

// MARK: - Codable Conformance

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImageGenerationOutputOptions: Encodable {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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.

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
struct ImageGenerationParameters {
let sampleCount: Int?
let storageURI: String?
let negativePrompt: String?
let aspectRatio: String?
let safetyFilterLevel: String?
let personGeneration: String?
let outputOptions: ImageGenerationOutputOptions?
let addWatermark: Bool?
let includeResponsibleAIFilterReason: Bool?
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImageGenerationParameters: Equatable {}

// MARK: - Codable Conformance

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImageGenerationParameters: Encodable {
enum CodingKeys: String, CodingKey {
case sampleCount
case storageURI = "storageUri"
case negativePrompt
case aspectRatio
case safetyFilterLevel = "safetySetting"
case personGeneration
case outputOptions
case addWatermark
case includeResponsibleAIFilterReason = "includeRaiReason"
}

func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(sampleCount, forKey: .sampleCount)
try container.encodeIfPresent(storageURI, forKey: .storageURI)
try container.encodeIfPresent(negativePrompt, forKey: .negativePrompt)
try container.encodeIfPresent(aspectRatio, forKey: .aspectRatio)
try container.encodeIfPresent(safetyFilterLevel, forKey: .safetyFilterLevel)
try container.encodeIfPresent(personGeneration, forKey: .personGeneration)
try container.encodeIfPresent(outputOptions, forKey: .outputOptions)
try container.encodeIfPresent(addWatermark, forKey: .addWatermark)
try container.encodeIfPresent(
includeResponsibleAIFilterReason,
forKey: .includeResponsibleAIFilterReason
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// 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 Foundation

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
struct ImagenGenerationRequest<ImageType: ImagenImageRepresentable> {
let model: String
let options: RequestOptions
let instances: [ImageGenerationInstance]
let parameters: ImageGenerationParameters

init(model: String, options: RequestOptions, instances: [ImageGenerationInstance],
parameters: ImageGenerationParameters) {
self.model = model
self.options = options
self.instances = instances
self.parameters = parameters
}
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImagenGenerationRequest: GenerativeAIRequest where ImageType: Decodable {
typealias Response = ImagenGenerationResponse<ImageType>

var url: URL {
return URL(string: "\(Constants.baseURL)/\(options.apiVersion)/\(model):predict")!
}
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImagenGenerationRequest: Encodable {
enum CodingKeys: CodingKey {
case instances
case parameters
}

func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(instances, forKey: .instances)
try container.encode(parameters, forKey: .parameters)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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 Foundation

// TODO(andrewheard): Make this public when the SDK supports Imagen operations that take images as
// input (upscaling / editing).
@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
protocol ImagenImageRepresentable {
/// Internal representation of the image for use with the Imagen model.
///
/// - Important: Not needed by SDK users.
var _internalImagenImage: _InternalImagenImage { get }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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 Foundation

/// Internal representation of an image for the Imagen model.
///
/// - Important: For internal use by types conforming to ``ImagenImageRepresentable``; all
/// properties are `internal` and are not needed by SDK users.
///
/// TODO(andrewheard): Make this public when the SDK supports Imagen operations that take images as
/// input (upscaling / editing).
@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
struct _InternalImagenImage {
let mimeType: String
let bytesBase64Encoded: String?
let gcsURI: String?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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.

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
struct RAIFilteredReason {
let raiFilteredReason: String
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension RAIFilteredReason: Decodable {
enum CodingKeys: CodingKey {
case raiFilteredReason
}
}
5 changes: 5 additions & 0 deletions FirebaseVertexAI/Sources/Types/Internal/InternalPart.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ struct FileData: Codable, Equatable, Sendable {
self.fileURI = fileURI
self.mimeType = mimeType
}

enum CodingKeys: String, CodingKey {
case fileURI = "fileUri"
case mimeType
}
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// 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 Foundation

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
public struct ImagenAspectRatio {
public static let square1x1 = ImagenAspectRatio(kind: .square1x1)

public static let portrait9x16 = ImagenAspectRatio(kind: .portrait9x16)

public static let landscape16x9 = ImagenAspectRatio(kind: .landscape16x9)

public static let portrait3x4 = ImagenAspectRatio(kind: .portrait3x4)

public static let landscape4x3 = ImagenAspectRatio(kind: .landscape4x3)

let rawValue: String
}

@available(iOS 15.0, macOS 12.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
extension ImagenAspectRatio: ProtoEnum {
enum Kind: String {
case square1x1 = "1:1"
case portrait9x16 = "9:16"
case landscape16x9 = "16:9"
case portrait3x4 = "3:4"
case landscape4x3 = "4:3"
}
}
Loading
Loading