Conversation
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for grounding with Google Maps, a valuable addition to the SDK's capabilities. The changes are well-structured, adding new data types for tool configuration and response handling, along with comprehensive unit and integration tests. My feedback includes a couple of minor suggestions: one to correct a documentation typo and another to add input validation for increased robustness. I've also proposed some refactoring in the new integration tests to enhance their clarity and conciseness.
FirebaseAI/Tests/TestApp/Tests/Integration/MapsGroundingIntegrationTests.swift
Outdated
Show resolved
Hide resolved
FirebaseAI/Tests/TestApp/Tests/Integration/MapsGroundingIntegrationTests.swift
Outdated
Show resolved
Hide resolved
6cd64a0 to
67fa59f
Compare
There was a problem hiding this comment.
nit: Should we put this file in Sources/Types/Public/Tools?
FirebaseAI/Sources/GoogleMaps.swift
Outdated
| /// > Important: When using this feature, you are required to comply with the | ||
| /// "Grounding with Google Maps" usage requirements for your chosen API provider. | ||
| public struct GoogleMaps: Sendable, Encodable { | ||
| public init() {} |
There was a problem hiding this comment.
nit: Let's keep the initializer internal until we need to expose it.
FirebaseAI/Sources/Tool.swift
Outdated
| public static func googleMaps(_ googleMaps: GoogleMaps = GoogleMaps()) -> Tool { | ||
| return self.init(googleMaps: googleMaps) |
There was a problem hiding this comment.
| public static func googleMaps(_ googleMaps: GoogleMaps = GoogleMaps()) -> Tool { | |
| return self.init(googleMaps: googleMaps) | |
| public static func googleMaps() -> Tool { | |
| return self.init(googleMaps: GoogleMaps()) |
| public let latLng: LatLng | ||
|
|
||
| public init(latLng: LatLng) { | ||
| self.latLng = latLng | ||
| } | ||
|
|
||
| enum CodingKeys: String, CodingKey { | ||
| case latLng = "lat_lng" | ||
| } | ||
| } | ||
|
|
||
| /// An object that represents a latitude/longitude pair. | ||
| public struct LatLng: Sendable, Encodable { | ||
| /// The latitude in degrees. It must be in the range [-90.0, +90.0]. | ||
| public let latitude: Double | ||
| /// The longitude in degrees. It must be in the range [-180.0, +180.0]. | ||
| public let longitude: Double | ||
|
|
||
| public init(latitude: Double, longitude: Double) { | ||
| precondition( | ||
| latitude >= -90.0 && latitude <= 90.0, | ||
| "Latitude must be in the range [-90.0, 90.0]." | ||
| ) | ||
| precondition( | ||
| longitude >= -180.0 && longitude <= 180.0, | ||
| "Longitude must be in the range [-180.0, 180.0]." | ||
| ) | ||
| self.latitude = latitude | ||
| self.longitude = longitude |
There was a problem hiding this comment.
Consider hiding the questionably named LatLng with an initializer that takes latitude and longitude:
| public let latLng: LatLng | |
| public init(latLng: LatLng) { | |
| self.latLng = latLng | |
| } | |
| enum CodingKeys: String, CodingKey { | |
| case latLng = "lat_lng" | |
| } | |
| } | |
| /// An object that represents a latitude/longitude pair. | |
| public struct LatLng: Sendable, Encodable { | |
| /// The latitude in degrees. It must be in the range [-90.0, +90.0]. | |
| public let latitude: Double | |
| /// The longitude in degrees. It must be in the range [-180.0, +180.0]. | |
| public let longitude: Double | |
| public init(latitude: Double, longitude: Double) { | |
| precondition( | |
| latitude >= -90.0 && latitude <= 90.0, | |
| "Latitude must be in the range [-90.0, 90.0]." | |
| ) | |
| precondition( | |
| longitude >= -180.0 && longitude <= 180.0, | |
| "Longitude must be in the range [-180.0, 180.0]." | |
| ) | |
| self.latitude = latitude | |
| self.longitude = longitude | |
| let latLng: LatLng | |
| init(latLng: LatLng) { | |
| self.latLng = latLng | |
| } | |
| public init(latitude: Double, longitude: Double) { | |
| assert( | |
| latitude >= -90.0 && latitude <= 90.0, | |
| "Latitude must be in the range [-90.0, 90.0]." | |
| ) | |
| assert( | |
| longitude >= -180.0 && longitude <= 180.0, | |
| "Longitude must be in the range [-180.0, 180.0]." | |
| ) | |
| self.latLng = LatLng(latitude: latitude, longitude: longitude) | |
| } | |
| } | |
| /// An object that represents a latitude/longitude pair. | |
| struct LatLng: Sendable, Encodable { | |
| /// The latitude in degrees. It must be in the range [-90.0, +90.0]. | |
| let latitude: Double | |
| /// The longitude in degrees. It must be in the range [-180.0, +180.0]. | |
| let longitude: Double | |
| init(latitude: Double, longitude: Double) { |
or using the platform-native type CLLocationCoordinate2D:
| public let latLng: LatLng | |
| public init(latLng: LatLng) { | |
| self.latLng = latLng | |
| } | |
| enum CodingKeys: String, CodingKey { | |
| case latLng = "lat_lng" | |
| } | |
| } | |
| /// An object that represents a latitude/longitude pair. | |
| public struct LatLng: Sendable, Encodable { | |
| /// The latitude in degrees. It must be in the range [-90.0, +90.0]. | |
| public let latitude: Double | |
| /// The longitude in degrees. It must be in the range [-180.0, +180.0]. | |
| public let longitude: Double | |
| public init(latitude: Double, longitude: Double) { | |
| precondition( | |
| latitude >= -90.0 && latitude <= 90.0, | |
| "Latitude must be in the range [-90.0, 90.0]." | |
| ) | |
| precondition( | |
| longitude >= -180.0 && longitude <= 180.0, | |
| "Longitude must be in the range [-180.0, 180.0]." | |
| ) | |
| self.latitude = latitude | |
| self.longitude = longitude | |
| let latLng: LatLng | |
| init(latLng: LatLng) { | |
| self.latLng = latLng | |
| } | |
| public init(location: CLLocationCoordinate2D) { | |
| assert(CLLocationCoordinate2DIsValid(location), """ | |
| Latitude must be in the range [-90.0, 90.0] and longitude must be in the range [-180.0, 180.0]. | |
| """) | |
| self.latLng = LatLng(latitude: location.latitude, longitude: location.longitude) | |
| } | |
| } | |
| /// An object that represents a latitude/longitude pair. | |
| struct LatLng: Sendable, Encodable { | |
| /// The latitude in degrees. It must be in the range [-90.0, +90.0]. | |
| let latitude: Double | |
| /// The longitude in degrees. It must be in the range [-180.0, +180.0]. | |
| let longitude: Double | |
| init(latitude: Double, longitude: Double) { |
The latter would require import CoreLocation.
There was a problem hiding this comment.
I thought we agreed with the group that LatLng should be public across platforms?
FirebaseAI/Sources/Tool.swift
Outdated
| enum CodingKeys: String, CodingKey { | ||
| case latLng = "lat_lng" | ||
| } |
There was a problem hiding this comment.
nit: This can be deleted.
FirebaseAI/Sources/Tool.swift
Outdated
| extension ToolConfig: Encodable {} | ||
| extension ToolConfig: Encodable { | ||
| enum CodingKeys: String, CodingKey { | ||
| case functionCallingConfig | ||
| case retrievalConfig = "retrieval_config" | ||
| } | ||
| } |
There was a problem hiding this comment.
nit: This should be reverted.
| } | ||
|
|
||
| /// A grounding chunk sourced from Google Maps. | ||
| public struct GoogleMapsGroundingChunk: Sendable, Equatable, Hashable, Decodable { |
There was a problem hiding this comment.
nit: Should this be nested inside GroundingMetadata to align with GroundingMetadata.WebGroundingChunk?
There was a problem hiding this comment.
Not sure. It might be better to move WebGroundingChunk to its own file to align with Maps Grounding?
FirebaseAI/Sources/GoogleMaps.swift
Outdated
| public let uri: String | ||
| /// The title of the retrieved map data. | ||
| public let title: String | ||
| /// The Place ID of the retrieved map data. | ||
| public let placeID: String |
There was a problem hiding this comment.
Are these guaranteed to be non-nil?
There was a problem hiding this comment.
Is there a recommended way to find out?
FirebaseAI/Sources/GoogleMaps.swift
Outdated
| /// A grounding chunk sourced from Google Maps. | ||
| public struct GoogleMapsGroundingChunk: Sendable, Equatable, Hashable, Decodable { | ||
| /// The URI of the retrieved map data. | ||
| public let uri: String |
There was a problem hiding this comment.
Would it be more idiomatic to provide a URL in Swift?
| } | ||
|
|
||
| /// A grounding chunk sourced from Google Maps. | ||
| public struct GoogleMapsGroundingChunk: Sendable, Equatable, Hashable, Decodable { |
There was a problem hiding this comment.
Did we intentionally exclude text and placeAnswerSources?
There was a problem hiding this comment.
Ongoing discussion in the API review. I haven't been able to get text included in a response.
Generated by 🚫 Danger |
| /// The URL of the retrieved map data. | ||
| public let url: URL? | ||
| /// The title of the retrieved map data. | ||
| public let title: String |
There was a problem hiding this comment.
Make these either nullable or defensively decode.
Inspired by firebase/firebase-js-sdk#9458
TODO: ADD text field and update integration test