Skip to content

Commit

Permalink
[Vertex AI] Update logging details from Google AI SDK (#12933)
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewheard committed May 13, 2024
1 parent a03e51a commit e36744b
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 29 deletions.
10 changes: 6 additions & 4 deletions FirebaseVertexAI/Sources/GenerateContentResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public struct GenerateContentResponse {
/// The response's content as text, if it exists.
public var text: String? {
guard let candidate = candidates.first else {
Logging.default.error("Could not get text from a response that had no candidates.")
Logging.default
.error("[FirebaseVertexAI] Could not get text from a response that had no candidates.")
return nil
}
let textValues: [String] = candidate.content.parts.compactMap { part in
Expand All @@ -52,7 +53,8 @@ public struct GenerateContentResponse {
return text
}
guard textValues.count > 0 else {
Logging.default.error("Could not get a text part from the first candidate.")
Logging.default
.error("[FirebaseVertexAI] Could not get a text part from the first candidate.")
return nil
}
return textValues.joined(separator: " ")
Expand Down Expand Up @@ -319,7 +321,7 @@ extension FinishReason: Decodable {
let value = try decoder.singleValueContainer().decode(String.self)
guard let decodedFinishReason = FinishReason(rawValue: value) else {
Logging.default
.error("[GoogleGenerativeAI] Unrecognized FinishReason with value \"\(value)\".")
.error("[FirebaseVertexAI] Unrecognized FinishReason with value \"\(value)\".")
self = .unknown
return
}
Expand All @@ -334,7 +336,7 @@ extension PromptFeedback.BlockReason: Decodable {
let value = try decoder.singleValueContainer().decode(String.self)
guard let decodedBlockReason = PromptFeedback.BlockReason(rawValue: value) else {
Logging.default
.error("[GoogleGenerativeAI] Unrecognized BlockReason with value \"\(value)\".")
.error("[FirebaseVertexAI] Unrecognized BlockReason with value \"\(value)\".")
self = .unknown
return
}
Expand Down
20 changes: 10 additions & 10 deletions FirebaseVertexAI/Sources/GenerativeAIService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ struct GenerativeAIService {

// Verify the status code is 200
guard response.statusCode == 200 else {
Logging.default.error("[GoogleGenerativeAI] The server responded with an error: \(response)")
Logging.default.error("[FirebaseVertexAI] The server responded with an error: \(response)")
if let responseString = String(data: data, encoding: .utf8) {
Logging.network.error("[GoogleGenerativeAI] Response payload: \(responseString)")
Logging.network.error("[FirebaseVertexAI] Response payload: \(responseString)")
}

throw parseError(responseData: data)
Expand Down Expand Up @@ -105,13 +105,13 @@ struct GenerativeAIService {
// Verify the status code is 200
guard response.statusCode == 200 else {
Logging.default
.error("[GoogleGenerativeAI] The server responded with an error: \(response)")
.error("[FirebaseVertexAI] The server responded with an error: \(response)")
var responseBody = ""
for try await line in stream.lines {
responseBody += line + "\n"
}

Logging.network.error("[GoogleGenerativeAI] Response payload: \(responseBody)")
Logging.network.error("[FirebaseVertexAI] Response payload: \(responseBody)")
continuation.finish(throwing: parseError(responseBody: responseBody))

return
Expand All @@ -123,7 +123,7 @@ struct GenerativeAIService {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
for try await line in stream.lines {
Logging.network.debug("[GoogleGenerativeAI] Stream response: \(line)")
Logging.network.debug("[FirebaseVertexAI] Stream response: \(line)")

if line.hasPrefix("data:") {
// We can assume 5 characters since it's utf-8 encoded, removing `data:`.
Expand Down Expand Up @@ -176,7 +176,7 @@ struct GenerativeAIService {
urlRequest.setValue(tokenResult.token, forHTTPHeaderField: "X-Firebase-AppCheck")
if let error = tokenResult.error {
Logging.default
.debug("[GoogleGenerativeAI] Failed to fetch AppCheck token. Error: \(error)")
.debug("[FirebaseVertexAI] Failed to fetch AppCheck token. Error: \(error)")
}
}

Expand All @@ -200,7 +200,7 @@ struct GenerativeAIService {
guard let response = urlResponse as? HTTPURLResponse else {
Logging.default
.error(
"[GoogleGenerativeAI] Response wasn't an HTTP response, internal error \(urlResponse)"
"[FirebaseVertexAI] Response wasn't an HTTP response, internal error \(urlResponse)"
)
throw NSError(
domain: "com.google.generative-ai",
Expand Down Expand Up @@ -248,9 +248,9 @@ struct GenerativeAIService {
return try JSONDecoder().decode(type, from: data)
} catch {
if let json = String(data: data, encoding: .utf8) {
Logging.network.error("[GoogleGenerativeAI] JSON response: \(json)")
Logging.network.error("[FirebaseVertexAI] JSON response: \(json)")
}
Logging.default.error("[GoogleGenerativeAI] Error decoding server JSON: \(error)")
Logging.default.error("[FirebaseVertexAI] Error decoding server JSON: \(error)")
throw error
}
}
Expand Down Expand Up @@ -278,7 +278,7 @@ struct GenerativeAIService {
private func printCURLCommand(from request: URLRequest) {
let command = cURLCommand(from: request)
Logging.verbose.debug("""
[GoogleGenerativeAI] Creating request with the equivalent cURL command:
[FirebaseVertexAI] Creating request with the equivalent cURL command:
----- cURL command -----
\(command, privacy: .private)
------------------------
Expand Down
25 changes: 17 additions & 8 deletions FirebaseVertexAI/Sources/GenerativeModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,23 @@ public final class GenerativeModel {
self.systemInstruction = systemInstruction
self.requestOptions = requestOptions

Logging.default.info("""
[GoogleGenerativeAI] Model \(
name,
privacy: .public
) initialized. To enable additional logging, add \
`\(Logging.enableArgumentKey, privacy: .public)` as a launch argument in Xcode.
""")
Logging.verbose.debug("[GoogleGenerativeAI] Verbose logging enabled.")
if Logging.additionalLoggingEnabled() {
if ProcessInfo.processInfo.arguments.contains(Logging.migrationEnableArgumentKey) {
Logging.verbose.debug("""
[FirebaseVertexAI] Verbose logging enabled with the \
\(Logging.migrationEnableArgumentKey, privacy: .public) launch argument; please migrate to \
the \(Logging.enableArgumentKey, privacy: .public) argument to ensure future compatibility.
""")
} else {
Logging.verbose.debug("[FirebaseVertexAI] Verbose logging enabled.")
}
} else {
Logging.default.info("""
[FirebaseVertexAI] To enable additional logging, add \
`\(Logging.enableArgumentKey, privacy: .public)` as a launch argument in Xcode.
""")
}
Logging.default.debug("[FirebaseVertexAI] Model \(name, privacy: .public) initialized.")
}

/// Generates content from String and/or image inputs, given to the model as a prompt, that are
Expand Down
23 changes: 19 additions & 4 deletions FirebaseVertexAI/Sources/Logging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ import OSLog
@available(iOS 15.0, macOS 11.0, macCatalyst 15.0, *)
struct Logging {
/// Subsystem that should be used for all Loggers.
static let subsystem = "com.google.generative-ai"
static let subsystem = "com.google.firebase.vertex-ai"

/// Default category used for most loggers, unless specialized.
static let defaultCategory = ""

/// The argument required to enable additional logging.
static let enableArgumentKey = "-GoogleGenerativeAIDebugLogEnabled"
static let enableArgumentKey = "-FIRDebugEnabled"

/// The argument required to enable additional logging in the Google AI SDK; used for migration.
///
/// To facillitate migration between the SDKs, this launch argument is also accepted to enable
/// additional logging at this time, though it is expected to be removed in the future.
static let migrationEnableArgumentKey = "-GoogleGenerativeAIDebugLogEnabled"

// No initializer available.
@available(*, unavailable)
Expand All @@ -36,7 +42,7 @@ struct Logging {

/// A non default
static var network: Logger = {
if ProcessInfo.processInfo.arguments.contains(enableArgumentKey) {
if additionalLoggingEnabled() {
return Logger(subsystem: subsystem, category: "NetworkResponse")
} else {
// Return a valid logger that's using `OSLog.disabled` as the logger, hiding everything.
Expand All @@ -46,11 +52,20 @@ struct Logging {

///
static var verbose: Logger = {
if ProcessInfo.processInfo.arguments.contains(enableArgumentKey) {
if additionalLoggingEnabled() {
return Logger(subsystem: subsystem, category: defaultCategory)
} else {
// Return a valid logger that's using `OSLog.disabled` as the logger, hiding everything.
return Logger(.disabled)
}
}()

/// Returns `true` if additional logging has been enabled via a launch argument.
static func additionalLoggingEnabled() -> Bool {
let arguments = ProcessInfo.processInfo.arguments
if arguments.contains(enableArgumentKey) || arguments.contains(migrationEnableArgumentKey) {
return true
}
return false
}
}
6 changes: 3 additions & 3 deletions FirebaseVertexAI/Sources/Safety.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ extension SafetyRating.HarmProbability: Codable {
let value = try decoder.singleValueContainer().decode(String.self)
guard let decodedProbability = SafetyRating.HarmProbability(rawValue: value) else {
Logging.default
.error("[GoogleGenerativeAI] Unrecognized HarmProbability with value \"\(value)\".")
.error("[FirebaseVertexAI] Unrecognized HarmProbability with value \"\(value)\".")
self = .unknown
return
}
Expand All @@ -169,7 +169,7 @@ extension SafetySetting.HarmCategory: Codable {
let value = try decoder.singleValueContainer().decode(String.self)
guard let decodedCategory = SafetySetting.HarmCategory(rawValue: value) else {
Logging.default
.error("[GoogleGenerativeAI] Unrecognized HarmCategory with value \"\(value)\".")
.error("[FirebaseVertexAI] Unrecognized HarmCategory with value \"\(value)\".")
self = .unknown
return
}
Expand All @@ -184,7 +184,7 @@ extension SafetySetting.BlockThreshold: Codable {
let value = try decoder.singleValueContainer().decode(String.self)
guard let decodedThreshold = SafetySetting.BlockThreshold(rawValue: value) else {
Logging.default
.error("[GoogleGenerativeAI] Unrecognized BlockThreshold with value \"\(value)\".")
.error("[FirebaseVertexAI] Unrecognized BlockThreshold with value \"\(value)\".")
self = .unknown
return
}
Expand Down

0 comments on commit e36744b

Please sign in to comment.