Skip to content

Commit 56a084b

Browse files
ncooke3copybara-github
authored andcommitted
Copybara import of the project:
-- ffebd66 by Nick Cooke <nickcooke@google.com>: Add copyrights -- 02bd4d5 by Nick Cooke <nickcooke@google.com>: style -- fb06f5a by Nick Cooke <36927374+ncooke3@users.noreply.github.com>: Apply suggestions from code review COPYBARA_INTEGRATE_REVIEW=#15903 from firebase:nc/GeneratedFirebaseAI fb06f5a PiperOrigin-RevId: 878712049
1 parent 32258fa commit 56a084b

22 files changed

+5294
-6295
lines changed

GeneratedFirebaseAI/Sources/AILog.swift

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import Foundation
1616
#if os(Linux)
17-
import FoundationNetworking
17+
import FoundationNetworking
1818
#endif
1919
import Logging
2020

@@ -131,19 +131,18 @@ enum AILog {
131131
/// `MessageCode.fallbackValueUsed`.
132132
/// - caller: The name of the unwrapped value; defaults to the name of the computed property or
133133
/// function name from which the unwrapping occurred.
134-
static func safeUnwrap<T>(
135-
_ optionalValue: T?,
136-
fallback fallbackValue: T,
137-
level: Logger.Level = .debug,
138-
code: MessageCode = .fallbackValueUsed,
139-
caller: String = #function
140-
) -> T {
134+
static func safeUnwrap<T>(_ optionalValue: T?,
135+
fallback fallbackValue: T,
136+
level: Logger.Level = .debug,
137+
code: MessageCode = .fallbackValueUsed,
138+
caller: String = #function) -> T {
141139
guard let unwrappedValue = optionalValue else {
142140
AILog.log(
143141
level: level, code: code,
144142
"""
145143
No value specified for '\(caller)' (\(T.self)); using fallback value '\(fallbackValue)'.
146-
""")
144+
"""
145+
)
147146
return fallbackValue
148147
}
149148
return unwrappedValue

GeneratedFirebaseAI/Sources/APIClient.swift

Lines changed: 68 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414

1515
import Foundation
1616
#if os(Linux)
17-
import FoundationNetworking
17+
import FoundationNetworking
1818
#endif
1919

20-
import FirebaseCore
2120
import FirebaseAppCheckInterop
2221
import FirebaseAuthInterop
22+
import FirebaseCore
2323

2424
@available(iOS 15.0, macOS 13.0, macCatalyst 15.0, tvOS 15.0, watchOS 8.0, *)
2525
public final class APIClient: Sendable {
26-
2726
/// The language of the SDK in the format `gl-<language>/<version>`.
2827
static let languageTag = "gl-swift/5"
2928

@@ -35,7 +34,7 @@ public final class APIClient: Sendable {
3534
let decoder = JSONDecoder()
3635

3736
public init(backend: Backend, authentication: AuthenticationMethod, urlSession: URLSession) {
38-
if case .firebase(let app, let useLimitedUseAppCheckTokens) = authentication {
37+
if case let .firebase(app, useLimitedUseAppCheckTokens) = authentication {
3938
guard let projectID = app.options.projectID else {
4039
fatalError("The Firebase app named \"\(app.name)\" has no project ID in its configuration.")
4140
}
@@ -59,13 +58,14 @@ public final class APIClient: Sendable {
5958
}
6059

6160
self.backend = backend
62-
self.authenticationMethod = authentication
61+
authenticationMethod = authentication
6362
self.urlSession = urlSession
6463
}
6564

66-
init(backend: Backend, authentication: AuthenticationMethod, urlSession: URLSession, firebaseInfo: FirebaseInfo?) {
65+
init(backend: Backend, authentication: AuthenticationMethod, urlSession: URLSession,
66+
firebaseInfo: FirebaseInfo?) {
6767
self.backend = backend
68-
self.authenticationMethod = authentication
68+
authenticationMethod = authentication
6969
self.urlSession = urlSession
7070
self.firebaseInfo = firebaseInfo
7171
}
@@ -104,17 +104,17 @@ public final class APIClient: Sendable {
104104
domain: "Swift SDK",
105105
code: 0,
106106
userInfo: [
107-
NSLocalizedFailureReasonErrorKey: "Invalid URL: \(baseURL())"
107+
NSLocalizedFailureReasonErrorKey: "Invalid URL: \(baseURL())",
108108
]
109109
)
110110
}
111111

112112
switch backend {
113-
case .vertexAI(_, _, _, let version):
113+
case let .vertexAI(_, _, _, version):
114114
// vertex uses v1beta1 instead of v1beta (unless you're using firebase)
115115
let versionName = version == .v1beta && !isFirebase() ? "v1beta1" : "\(version)"
116116
url = url.appendingPathComponent("/\(versionName)", isDirectory: true)
117-
case .googleAI(let version, _):
117+
case let .googleAI(version, _):
118118
url = url.appendingPathComponent("/\(version)", isDirectory: true)
119119
}
120120

@@ -134,9 +134,9 @@ public final class APIClient: Sendable {
134134
/// Also takes into account if the firebase proxy is being used.
135135
private func modelName(for model: String) -> String {
136136
switch backend {
137-
case .vertexAI(let location, let publisher, let projectId, _):
137+
case let .vertexAI(location, publisher, projectId, _):
138138
return "projects/\(projectId)/locations/\(location)/publishers/\(publisher)/models/\(model)"
139-
case .googleAI(_, let direct):
139+
case let .googleAI(_, direct):
140140
if !direct, let projectId = firebaseInfo?.projectID {
141141
return "projects/\(projectId)/models/\(model)"
142142
}
@@ -154,7 +154,7 @@ public final class APIClient: Sendable {
154154
if !isFirebase() {
155155
return "https://aiplatform.googleapis.com"
156156
}
157-
case .googleAI(_, let direct):
157+
case let .googleAI(_, direct):
158158
if direct || !isFirebase() {
159159
return "https://generativelanguage.googleapis.com"
160160
}
@@ -164,28 +164,26 @@ public final class APIClient: Sendable {
164164
return "https://firebasevertexai.googleapis.com"
165165
}
166166

167-
func loadRequest<RequestParams: Encodable, ResponseType: Decodable>(
168-
params: RequestParams,
169-
url: URL,
170-
method: String
171-
) async throws -> ResponseType {
167+
func loadRequest<RequestParams: Encodable, ResponseType: Decodable>(params: RequestParams,
168+
url: URL,
169+
method: String) async throws
170+
-> ResponseType {
172171
let urlRequest = try await urlRequest(params: params, url: url, method: method)
173172
return try await performRequest(urlRequest)
174173
}
175174

176-
func loadRequest<ResponseType: Decodable>(
177-
params: [String: Any],
178-
url: URL,
179-
method: String
180-
) async throws -> ResponseType {
175+
func loadRequest<ResponseType: Decodable>(params: [String: Any],
176+
url: URL,
177+
method: String) async throws -> ResponseType {
181178
let urlRequest = try await urlRequest(params: params, url: url, method: method)
182179
return try await performRequest(urlRequest)
183180
}
184181

185-
private func performRequest<ResponseType: Decodable>(_ urlRequest: URLRequest) async throws -> ResponseType {
186-
//#if DEBUG
187-
printCURLCommand(from: urlRequest)
188-
//#endif
182+
private func performRequest<ResponseType: Decodable>(_ urlRequest: URLRequest) async throws
183+
-> ResponseType {
184+
// #if DEBUG
185+
printCURLCommand(from: urlRequest)
186+
// #endif
189187

190188
let data: Data
191189
let rawResponse: URLResponse
@@ -220,13 +218,14 @@ public final class APIClient: Sendable {
220218
}
221219

222220
// TODO(daymxn): implement streaming support once we have proper support/testing for non streaming
223-
/// Loads a stream request where the parameters are a dictionary `[String: Any]`.
221+
/// Loads a stream request where the parameters are a dictionary `[String: Any]`.
224222
@available(macOS 13.0, *)
225-
func loadRequestStream<ResponseType: Decodable>(
226-
params: [String: Any],
227-
url: URL,
228-
method: String
229-
) -> AsyncThrowingStream<ResponseType, Error> {
223+
func loadRequestStream<ResponseType: Decodable>(params: [String: Any],
224+
url: URL,
225+
method: String) -> AsyncThrowingStream<
226+
ResponseType,
227+
Error
228+
> {
230229
return AsyncThrowingStream { continuation in
231230
// TODO: Implement actual streaming logic here.
232231
fatalError("Streaming implementation pending")
@@ -235,22 +234,18 @@ public final class APIClient: Sendable {
235234

236235
// MARK: - Private Helpers
237236

238-
private func urlRequest<Params: Encodable>(
239-
params: Params,
240-
url: URL,
241-
method: String
242-
) async throws -> URLRequest {
237+
private func urlRequest<Params: Encodable>(params: Params,
238+
url: URL,
239+
method: String) async throws -> URLRequest {
243240
var urlRequest = try await makeBaseURLRequest(url: url, method: method)
244241
encoder.userInfo[.configuration] = self
245242
urlRequest.httpBody = try encoder.encode(params)
246243
return urlRequest
247244
}
248245

249-
private func urlRequest(
250-
params: [String: Any],
251-
url: URL,
252-
method: String
253-
) async throws -> URLRequest {
246+
private func urlRequest(params: [String: Any],
247+
url: URL,
248+
method: String) async throws -> URLRequest {
254249
var urlRequest = try await makeBaseURLRequest(url: url, method: method)
255250
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: params)
256251
return urlRequest
@@ -261,9 +256,9 @@ public final class APIClient: Sendable {
261256
urlRequest.httpMethod = method
262257

263258
switch authenticationMethod {
264-
case .apiKey(let key):
259+
case let .apiKey(key):
265260
urlRequest.setValue(key, forHTTPHeaderField: "x-goog-api-key")
266-
case .accessToken(let token):
261+
case let .accessToken(token):
267262
urlRequest.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
268263
case .firebase:
269264
guard let firebaseInfo else {
@@ -311,7 +306,8 @@ public final class APIClient: Sendable {
311306
}
312307
}
313308

314-
if let auth = firebaseInfo.auth, let authToken = try await auth.getToken(forcingRefresh: false) {
309+
if let auth = firebaseInfo.auth,
310+
let authToken = try await auth.getToken(forcingRefresh: false) {
315311
urlRequest.setValue("Firebase \(authToken)", forHTTPHeaderField: "Authorization")
316312
}
317313

@@ -405,37 +401,37 @@ public final class APIClient: Sendable {
405401
}
406402

407403
// #if DEBUG
408-
private func cURLCommand(from request: URLRequest) -> String {
409-
var returnValue = "curl "
410-
if let allHeaders = request.allHTTPHeaderFields {
411-
for (key, value) in allHeaders {
412-
returnValue += "-H '\(key): \(value)' "
413-
}
404+
private func cURLCommand(from request: URLRequest) -> String {
405+
var returnValue = "curl "
406+
if let allHeaders = request.allHTTPHeaderFields {
407+
for (key, value) in allHeaders {
408+
returnValue += "-H '\(key): \(value)' "
414409
}
410+
}
415411

416-
guard let url = request.url else { return "" }
417-
returnValue += "'\(url.absoluteString)' "
412+
guard let url = request.url else { return "" }
413+
returnValue += "'\(url.absoluteString)' "
418414

419-
guard let body = request.httpBody,
420-
let jsonStr = String(bytes: body, encoding: .utf8) else { return "" }
421-
let escapedJSON = jsonStr.replacingOccurrences(of: "'", with: "'\\''")
422-
returnValue += "-d '\(escapedJSON)'"
415+
guard let body = request.httpBody,
416+
let jsonStr = String(bytes: body, encoding: .utf8) else { return "" }
417+
let escapedJSON = jsonStr.replacingOccurrences(of: "'", with: "'\\''")
418+
returnValue += "-d '\(escapedJSON)'"
423419

424-
return returnValue
425-
}
420+
return returnValue
421+
}
426422

427-
private func printCURLCommand(from request: URLRequest) {
428-
guard AILog.additionalLoggingEnabled() else {
429-
return
430-
}
431-
let command = cURLCommand(from: request)
432-
AILog.debug(code: .fallbackValueUsed,
433-
"""
434-
Creating request with the equivalent cURL command:
435-
----- cURL command -----
436-
\(command)
437-
------------------------
438-
""")
423+
private func printCURLCommand(from request: URLRequest) {
424+
guard AILog.additionalLoggingEnabled() else {
425+
return
439426
}
427+
let command = cURLCommand(from: request)
428+
AILog.debug(code: .fallbackValueUsed,
429+
"""
430+
Creating request with the equivalent cURL command:
431+
----- cURL command -----
432+
\(command)
433+
------------------------
434+
""")
435+
}
440436
// #endif // DEBUG
441437
}

GeneratedFirebaseAI/Sources/APIConfig.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import Foundation
1616
#if os(Linux)
17-
import FoundationNetworking
17+
import FoundationNetworking
1818
#endif
1919

2020
/// Configuration for the generative AI backend API used by this SDK.

GeneratedFirebaseAI/Sources/AuthenticationMethod.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import Foundation
1616
#if os(Linux)
17-
import FoundationNetworking
17+
import FoundationNetworking
1818
#endif
1919

2020
@preconcurrency import FirebaseCore

GeneratedFirebaseAI/Sources/Backend.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,25 @@
1414

1515
import Foundation
1616
#if os(Linux)
17-
import FoundationNetworking
17+
import FoundationNetworking
1818
#endif
1919

2020
/// API backend to communicate with.
2121
public enum Backend: Sendable {
2222
/// Use the [Vertex AI](https://cloud.google.com/vertex-ai/docs) backend.
2323
///
2424
/// - Parameters:
25-
/// - location: Geographic location for API requests to made to. For a list of supported locations, see the docs on
26-
/// [Available locations](https://docs.cloud.google.com/vertex-ai/docs/general/locations#available-regions)\.
25+
/// - location: Geographic location for API requests to made to. For a list of supported
26+
/// locations, see the docs on
27+
/// [Available
28+
/// locations](https://docs.cloud.google.com/vertex-ai/docs/general/locations#available-regions)\.
2729
/// Note that models and feature endpoints may have additional location restrictions.
2830
/// - publisher: The name of the model publisher to use for published models.
29-
/// - projectId: The GCloud project ID to use for resource consumption. When using the Firebase authentication method,
31+
/// - projectId: The GCloud project ID to use for resource consumption. When using the Firebase
32+
/// authentication method,
3033
/// you can retrieve the project ID via `FirebaseApp.options.projectID`.
31-
/// - version: Version of the backend to use. Feature support may vary across different backend versions.
34+
/// - version: Version of the backend to use. Feature support may vary across different backend
35+
/// versions.
3236
case vertexAI(
3337
location: String = "us-central1",
3438
publisher: String = "google",
@@ -39,8 +43,10 @@ public enum Backend: Sendable {
3943
/// Use the [Google AI](https://ai.google.dev/gemini-api/docs) backend.
4044
///
4145
/// - Parameters:
42-
/// - version: Version of the backend to use. Feature support may vary across different backend versions.
43-
/// - direct: Only applicable when using the Firebase authentication method. Instead of communicating through the Firebase
46+
/// - version: Version of the backend to use. Feature support may vary across different backend
47+
/// versions.
48+
/// - direct: Only applicable when using the Firebase authentication method. Instead of
49+
/// communicating through the Firebase
4450
/// proxy, communicate directly with the Google AI API.
4551
case googleAI(
4652
version: BackendVersion = .v1beta,

0 commit comments

Comments
 (0)