Skip to content

Commit 75999cc

Browse files
authored
[Firebase AI] Rename internal APIConfig enums (#14778)
1 parent f5f8fa5 commit 75999cc

13 files changed

+121
-112
lines changed

FirebaseAI/Sources/FirebaseAI.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public final class FirebaseAI: Sendable {
4242
)
4343
// Verify that the `FirebaseAI` instance is always configured with the production endpoint since
4444
// this is the public API surface for creating an instance.
45-
assert(instance.apiConfig.service.endpoint == .firebaseVertexAIProd)
45+
assert(instance.apiConfig.service.endpoint == .firebaseProxyProd)
4646
assert(instance.apiConfig.version == .v1beta)
4747
return instance
4848
}
@@ -150,7 +150,7 @@ public final class FirebaseAI: Sendable {
150150
let location: String?
151151

152152
static let defaultVertexAIAPIConfig = APIConfig(
153-
service: .vertexAI(endpoint: .firebaseVertexAIProd),
153+
service: .vertexAI(endpoint: .firebaseProxyProd),
154154
version: .v1beta
155155
)
156156

@@ -209,7 +209,7 @@ public final class FirebaseAI: Sendable {
209209
switch apiConfig.service {
210210
case .vertexAI:
211211
return vertexAIModelResourceName(modelName: modelName)
212-
case .developer:
212+
case .googleAI:
213213
return developerModelResourceName(modelName: modelName)
214214
}
215215
}
@@ -233,10 +233,10 @@ public final class FirebaseAI: Sendable {
233233

234234
private func developerModelResourceName(modelName: String) -> String {
235235
switch apiConfig.service.endpoint {
236-
case .firebaseVertexAIStaging, .firebaseVertexAIProd:
236+
case .firebaseProxyStaging, .firebaseProxyProd:
237237
let projectID = firebaseInfo.projectID
238238
return "projects/\(projectID)/models/\(modelName)"
239-
case .generativeLanguage:
239+
case .googleAIBypassProxy:
240240
return "models/\(modelName)"
241241
}
242242
}

FirebaseAI/Sources/GenerativeModel.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ public final class GenerativeModel: Sendable {
277277
let requestContent = switch apiConfig.service {
278278
case .vertexAI:
279279
content
280-
case .developer:
280+
case .googleAI:
281281
// The `role` defaults to "user" but is ignored in `countTokens`. However, it is erroneously
282282
// erroneously counted towards the prompt and total token count when using the Developer API
283283
// backend; set to `nil` to avoid token count discrepancies between `countTokens` and
@@ -290,10 +290,10 @@ public final class GenerativeModel: Sendable {
290290
// "models/model-name". This field is unaltered by the Firebase backend before forwarding the
291291
// request to the Generative Language backend, which expects the form "models/model-name".
292292
let generateContentRequestModelResourceName = switch apiConfig.service {
293-
case .vertexAI, .developer(endpoint: .generativeLanguage):
293+
case .vertexAI, .googleAI(endpoint: .googleAIBypassProxy):
294294
modelResourceName
295-
case .developer(endpoint: .firebaseVertexAIProd),
296-
.developer(endpoint: .firebaseVertexAIStaging):
295+
case .googleAI(endpoint: .firebaseProxyProd),
296+
.googleAI(endpoint: .firebaseProxyStaging):
297297
"models/\(modelName)"
298298
}
299299

FirebaseAI/Sources/Types/Internal/APIConfig.swift

+21-12
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// limitations under the License.
1414

1515
/// Configuration for the generative AI backend API used by this SDK.
16-
struct APIConfig: Sendable, Hashable {
16+
struct APIConfig: Sendable, Hashable, Encodable {
1717
/// The service to use for generative AI.
1818
///
1919
/// This controls which backend API is used by the SDK.
@@ -39,7 +39,7 @@ extension APIConfig {
3939
/// See [Vertex AI and Google AI
4040
/// differences](https://cloud.google.com/vertex-ai/generative-ai/docs/overview#how-gemini-vertex-different-gemini-aistudio)
4141
/// for a comparison of the two [API services](https://google.aip.dev/9#api-service).
42-
enum Service: Hashable {
42+
enum Service: Hashable, Encodable {
4343
/// The Gemini Enterprise API provided by Vertex AI.
4444
///
4545
/// See the [Cloud
@@ -50,7 +50,7 @@ extension APIConfig {
5050
/// The Gemini Developer API provided by Google AI.
5151
///
5252
/// See the [Google AI docs](https://ai.google.dev/gemini-api/docs) for more details.
53-
case developer(endpoint: Endpoint)
53+
case googleAI(endpoint: Endpoint)
5454

5555
/// The specific network address to use for API requests.
5656
///
@@ -59,7 +59,7 @@ extension APIConfig {
5959
switch self {
6060
case let .vertexAI(endpoint: endpoint):
6161
return endpoint
62-
case let .developer(endpoint: endpoint):
62+
case let .googleAI(endpoint: endpoint):
6363
return endpoint
6464
}
6565
}
@@ -68,21 +68,30 @@ extension APIConfig {
6868

6969
extension APIConfig.Service {
7070
/// Network addresses for generative AI API services.
71-
enum Endpoint: String {
72-
/// The Firebase AI SDK production endpoint.
73-
case firebaseVertexAIProd = "https://firebasevertexai.googleapis.com"
71+
enum Endpoint: String, Encodable {
72+
/// The Firebase proxy production endpoint.
73+
///
74+
/// This endpoint supports both Google AI and Vertex AI.
75+
case firebaseProxyProd = "https://firebasevertexai.googleapis.com"
7476

75-
/// The Firebase AI SDK staging endpoint; for SDK development and testing only.
76-
case firebaseVertexAIStaging = "https://staging-firebasevertexai.sandbox.googleapis.com"
77+
/// The Firebase proxy staging endpoint; for SDK development and testing only.
78+
///
79+
/// This endpoint supports both the Gemini Developer API (commonly referred to as Google AI)
80+
/// and the Gemini API in Vertex AI (commonly referred to simply as Vertex AI).
81+
case firebaseProxyStaging = "https://staging-firebasevertexai.sandbox.googleapis.com"
7782

78-
/// The Gemini Developer API production endpoint; for SDK development and testing only.
79-
case generativeLanguage = "https://generativelanguage.googleapis.com"
83+
/// The Gemini Developer API (Google AI) direct production endpoint; for SDK development and
84+
/// testing only.
85+
///
86+
/// This bypasses the Firebase proxy and directly connects to the Gemini Developer API
87+
/// (Google AI) backend. This endpoint only supports the Gemini Developer API, not Vertex AI.
88+
case googleAIBypassProxy = "https://generativelanguage.googleapis.com"
8089
}
8190
}
8291

8392
extension APIConfig {
8493
/// Versions of the configured API service (`APIConfig.Service`).
85-
enum Version: String {
94+
enum Version: String, Encodable {
8695
/// The stable channel for version 1 of the API.
8796
case v1
8897

FirebaseAI/Sources/Types/Internal/Requests/CountTokensRequest.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ extension CountTokensRequest: Encodable {
7171
switch apiConfig.service {
7272
case .vertexAI:
7373
try encodeForVertexAI(to: encoder)
74-
case .developer:
74+
case .googleAI:
7575
try encodeForDeveloper(to: encoder)
7676
}
7777
}

FirebaseAI/Sources/Types/Public/Backend.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ public struct Backend {
2525
/// for a list of supported locations.
2626
public static func vertexAI(location: String = "us-central1") -> Backend {
2727
return Backend(
28-
apiConfig: APIConfig(service: .vertexAI(endpoint: .firebaseVertexAIProd), version: .v1beta),
28+
apiConfig: APIConfig(service: .vertexAI(endpoint: .firebaseProxyProd), version: .v1beta),
2929
location: location
3030
)
3131
}
3232

3333
/// Initializes a `Backend` configured for the Google Developer API.
3434
public static func googleAI() -> Backend {
3535
return Backend(
36-
apiConfig: APIConfig(service: .developer(endpoint: .firebaseVertexAIProd), version: .v1beta),
36+
apiConfig: APIConfig(service: .googleAI(endpoint: .firebaseProxyProd), version: .v1beta),
3737
location: nil
3838
)
3939
}

FirebaseAI/Tests/TestApp/Tests/Integration/CountTokensIntegrationTests.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct CountTokensIntegrationTests {
6060
switch config.apiConfig.service {
6161
case .vertexAI:
6262
#expect(response.totalBillableCharacters == 16)
63-
case .developer:
63+
case .googleAI:
6464
#expect(response.totalBillableCharacters == nil)
6565
}
6666
#expect(response.promptTokensDetails.count == 1)
@@ -71,7 +71,7 @@ struct CountTokensIntegrationTests {
7171

7272
@Test(
7373
/* System instructions are not supported on the v1 Developer API. */
74-
arguments: InstanceConfig.allConfigsExceptDeveloperV1
74+
arguments: InstanceConfig.allConfigsExceptGoogleAI_v1
7575
)
7676
func countTokens_text_systemInstruction(_ config: InstanceConfig) async throws {
7777
let model = FirebaseAI.componentInstance(config).generativeModel(
@@ -87,7 +87,7 @@ struct CountTokensIntegrationTests {
8787
switch config.apiConfig.service {
8888
case .vertexAI:
8989
#expect(response.totalBillableCharacters == 61)
90-
case .developer:
90+
case .googleAI:
9191
#expect(response.totalBillableCharacters == nil)
9292
}
9393
#expect(response.promptTokensDetails.count == 1)
@@ -98,7 +98,7 @@ struct CountTokensIntegrationTests {
9898

9999
@Test(arguments: [
100100
/* System instructions are not supported on the v1 Developer API. */
101-
InstanceConfig.developerV1Spark,
101+
InstanceConfig.googleAI_v1_freeTier_bypassProxy,
102102
])
103103
func countTokens_text_systemInstruction_unsupported(_ config: InstanceConfig) async throws {
104104
let model = FirebaseAI.componentInstance(config).generativeModel(
@@ -120,7 +120,7 @@ struct CountTokensIntegrationTests {
120120

121121
@Test(
122122
/* System instructions are not supported on the v1 Developer API. */
123-
arguments: InstanceConfig.allConfigsExceptDeveloperV1
123+
arguments: InstanceConfig.allConfigsExceptGoogleAI_v1
124124
)
125125
func countTokens_jsonSchema(_ config: InstanceConfig) async throws {
126126
let model = FirebaseAI.componentInstance(config).generativeModel(
@@ -144,7 +144,7 @@ struct CountTokensIntegrationTests {
144144
case .vertexAI:
145145
#expect(response.totalTokens == 65)
146146
#expect(response.totalBillableCharacters == 170)
147-
case .developer:
147+
case .googleAI:
148148
// The Developer API erroneously ignores the `responseSchema` when counting tokens, resulting
149149
// in a lower total count than Vertex AI.
150150
#expect(response.totalTokens == 34)

FirebaseAI/Tests/TestApp/Tests/Integration/GenerateContentIntegrationTests.swift

+5-10
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ struct GenerateContentIntegrationTests {
7878
@Test(
7979
"Generate an enum and provide a system instruction",
8080
/* System instructions are not supported on the v1 Developer API. */
81-
arguments: InstanceConfig.allConfigsExceptDeveloperV1
81+
arguments: InstanceConfig.allConfigsExceptGoogleAI_v1
8282
)
8383
func generateContentEnum(_ config: InstanceConfig) async throws {
8484
let model = FirebaseAI.componentInstance(config).generativeModel(
@@ -118,9 +118,9 @@ struct GenerateContentIntegrationTests {
118118
// TODO(andrewheard): Vertex AI configs temporarily disabled to due empty SafetyRatings bug.
119119
// InstanceConfig.vertexV1,
120120
// InstanceConfig.vertexV1Beta,
121-
InstanceConfig.developerV1Beta,
122-
InstanceConfig.developerV1BetaStaging,
123-
InstanceConfig.developerV1BetaSpark,
121+
InstanceConfig.googleAI_v1beta,
122+
InstanceConfig.googleAI_v1beta_staging,
123+
InstanceConfig.googleAI_v1beta_freeTier_bypassProxy,
124124
])
125125
func generateImage(_ config: InstanceConfig) async throws {
126126
let generationConfig = GenerationConfig(
@@ -216,12 +216,7 @@ struct GenerateContentIntegrationTests {
216216

217217
// MARK: - App Check Tests
218218

219-
@Test(arguments: [
220-
InstanceConfig.vertexV1AppCheckNotConfigured,
221-
InstanceConfig.vertexV1BetaAppCheckNotConfigured,
222-
// App Check is not supported on the Generative Language Developer API endpoint since it
223-
// bypasses the Firebase AI SDK proxy.
224-
])
219+
@Test(arguments: InstanceConfig.appCheckNotConfiguredConfigs)
225220
func generateContent_appCheckNotConfigured_shouldFail(_ config: InstanceConfig) async throws {
226221
let model = FirebaseAI.componentInstance(config).generativeModel(
227222
modelName: ModelNames.gemini2Flash

FirebaseAI/Tests/TestApp/Tests/Integration/SchemaTests.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct SchemaTests {
4848
storage = Storage.storage()
4949
}
5050

51-
@Test(arguments: InstanceConfig.allConfigsExceptDeveloperV1)
51+
@Test(arguments: InstanceConfig.allConfigsExceptGoogleAI_v1)
5252
func generateContentSchemaItems(_ config: InstanceConfig) async throws {
5353
let model = FirebaseAI.componentInstance(config).generativeModel(
5454
modelName: ModelNames.gemini2FlashLite,
@@ -73,7 +73,7 @@ struct SchemaTests {
7373
#expect(decodedJSON.count <= 5, "Expected at most 5 cities, but got \(decodedJSON.count)")
7474
}
7575

76-
@Test(arguments: InstanceConfig.allConfigsExceptDeveloperV1)
76+
@Test(arguments: InstanceConfig.allConfigsExceptGoogleAI_v1)
7777
func generateContentSchemaNumberRange(_ config: InstanceConfig) async throws {
7878
let model = FirebaseAI.componentInstance(config).generativeModel(
7979
modelName: ModelNames.gemini2FlashLite,
@@ -96,7 +96,7 @@ struct SchemaTests {
9696
#expect(decodedNumber <= 120.0, "Expected a number <= 120, but got \(decodedNumber)")
9797
}
9898

99-
@Test(arguments: InstanceConfig.allConfigsExceptDeveloperV1)
99+
@Test(arguments: InstanceConfig.allConfigsExceptGoogleAI_v1)
100100
func generateContentSchemaNumberRangeMultiType(_ config: InstanceConfig) async throws {
101101
struct ProductInfo: Codable {
102102
let productName: String
@@ -149,7 +149,7 @@ struct SchemaTests {
149149
#expect(rating <= 5, "Expected a rating <= 5, but got \(rating)")
150150
}
151151

152-
@Test(arguments: InstanceConfig.allConfigsExceptDeveloperV1)
152+
@Test(arguments: InstanceConfig.allConfigsExceptGoogleAI_v1)
153153
func generateContentAnyOfSchema(_ config: InstanceConfig) async throws {
154154
struct MailingAddress: Decodable {
155155
let streetAddress: String

0 commit comments

Comments
 (0)