Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Update dependencies and add new firebase-ai APIs#49

Merged
uny merged 3 commits into
mainuny/firebase-kotlin-sdk:mainfrom
update-deps-and-firebase-ai-apisuny/firebase-kotlin-sdk:update-deps-and-firebase-ai-apisCopy head branch name to clipboard
May 28, 2026
Merged

Update dependencies and add new firebase-ai APIs#49
uny merged 3 commits into
mainuny/firebase-kotlin-sdk:mainfrom
update-deps-and-firebase-ai-apisuny/firebase-kotlin-sdk:update-deps-and-firebase-ai-apisCopy head branch name to clipboard

Conversation

@uny

@uny uny commented May 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • Update all dependencies to latest versions (AGP 9.1.1, Firebase BOM 34.13.0, Firebase Apple SDK 12.14.0, firebase-objc-sdk 0.5.0, kotlinx-coroutines 1.11.0, kotlinx-datetime 0.8.0, kotlinx-serialization 1.11.0)
  • Migrate Timestamp from kotlinx.datetime to kotlin.time (Clock, Instant)
  • Add new firebase-ai APIs matching BOM 34.13.0 / objc-sdk v0.5.0:
    • ImageConfig, AspectRatio, ImageSize for Gemini image generation
    • Tool.GoogleMaps, GoogleMapsGroundingChunk, RetrievalConfig, LatLng for Google Maps grounding
    • ContextWindowCompressionConfig, SlidingWindow for live session context compression
    • SessionResumptionConfig, LiveSession.resumeSession(), LiveServerMessage.SessionResumptionUpdate for session resumption
    • 10 new FinishReason cases, Candidate.finishMessage, GenerationConfig.imageConfig, ToolConfig.retrievalConfig, LiveGenerationConfig.contextWindowCompression

Test plan

  • firebase-ai Android + iOS targets compile successfully
  • firebase-common compiles with kotlin.time migration
  • firebase-app, firebase-auth compile successfully
  • Run full test suite on CI

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added image generation configuration with aspect ratio and size options
    • Enabled live session resumption for persistent conversation management
    • Added Google Maps grounding for citation sources
    • Introduced context window compression for optimized session handling
    • Expanded finish reason reporting with additional completion states
  • Chores

    • Updated Firebase SDK and dependency versions
    • Migrated time handling implementation to newer Kotlin time APIs

Review Change Stack

Update all dependencies to latest versions:
- AGP 9.1.0 → 9.1.1
- Firebase BOM 34.11.0 → 34.13.0
- Firebase Apple SDK 12.12.0 → 12.14.0
- firebase-objc-sdk 0.4.0 → 0.5.0
- kotlinx-coroutines 1.10.2 → 1.11.0
- kotlinx-datetime 0.7.1-0.6.x-compat → 0.8.0
- kotlinx-serialization 1.8.1 → 1.11.0

Migrate Timestamp from kotlinx.datetime to kotlin.time (Clock, Instant).

Add new firebase-ai APIs matching BOM 34.13.0 / objc-sdk v0.5.0:
- ImageConfig, AspectRatio, ImageSize for Gemini image generation
- GoogleMapsGroundingChunk and Tool.GoogleMaps for Maps grounding
- RetrievalConfig, LatLng for retrieval tool configuration
- ContextWindowCompressionConfig, SlidingWindow for live session compression
- SessionResumptionConfig and LiveSession.resumeSession() for session resumption
- LiveServerMessage.SessionResumptionUpdate for resumption state updates
- 10 new FinishReason cases (IMAGE_SAFETY, LANGUAGE, etc.)
- Candidate.finishMessage property
- GenerationConfig.imageConfig, ToolConfig.retrievalConfig
- LiveGenerationConfig.contextWindowCompression
- LiveGenerativeModel.connect(sessionResumption:) parameter

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@uny, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 36 minutes and 9 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: edfceda5-d272-41bb-a610-d1c41eb33017

📥 Commits

Reviewing files that changed from the base of the PR and between 269fdd0 and eeded0b.

📒 Files selected for processing (4)
  • firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/LiveSession.android.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/ImageConfig.kt
  • firebase-common/build.gradle.kts
  • gradle/libs.versions.toml
📝 Walkthrough

Walkthrough

This PR extends the Firebase AI Kotlin SDK with image generation capabilities, location-aware retrieval grounding via Google Maps, enhanced response metadata, live session context compression, and session resumption across Android and Apple platforms. It also migrates time types from kotlinx.datetime to kotlin.time and updates dependencies.

Changes

Firebase AI SDK Enhancements

Layer / File(s) Summary
Image generation and response metadata
firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/ImageConfig.kt, Enums.kt, GenerateContentResponse.kt, GenerationConfig.kt
Introduces ImageConfig with AspectRatio and ImageSize enums; extends FinishReason with image safety, language, tool-call, and response-quality termination states; adds finishMessage field to Candidate and wires imageConfig into GenerationConfig and its DSL builder.
Grounding and tool retrieval models
firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/GroundingMetadata.kt, Tool.kt
Extends GroundingChunk with GoogleMapsGroundingChunk for maps-based sources; adds Tool.GoogleMaps variant with factory; introduces RetrievalConfig and LatLng for location-aware retrieval; updates ToolConfig with optional retrievalConfig field.
Android platform image and grounding mapping
firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerationConfig.android.kt, GenerateContentResponse.android.kt, Tool.android.kt
Maps ImageConfig enums to Android SDK equivalents; extends finish-reason and grounding-chunk conversion to include new image and maps variants; adds GoogleMaps tool and RetrievalConfig mapping with latitude/longitude conversion.
Apple platform image and grounding mapping
firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/GenerationConfig.apple.kt, GenerateContentResponse.apple.kt, Tool.apple.kt
Maps ImageConfig enums to Apple KFBImageConfig SDK types; extends finish-reason and grounding-chunk conversion to include new image and maps variants; adds GoogleMaps tool and RetrievalConfig mapping with NSNumber coordinate conversion.
Live session context compression and resumption API
firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/ContextWindowCompressionConfig.kt, SessionResumptionConfig.kt, LiveGenerationConfig.kt, LiveGenerativeModel.kt, LiveSession.kt, LiveServerMessage.kt
Introduces ContextWindowCompressionConfig and SessionResumptionConfig configuration models; extends LiveGenerationConfig with context compression; updates LiveGenerativeModel.connect() to accept optional session resumption; adds LiveSession.resumeSession() API; adds SessionResumptionUpdate message type to server message stream.
Android live session resumption implementation
firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/LiveGenerativeModel.android.kt, LiveMapper.android.kt, LiveSession.android.kt
Implements conditional Android SDK calls in connect() based on resumption config presence; maps context compression and session resumption configs to Android types; handles AndroidLiveSessionResumptionUpdate messages; implements resumeSession() with config conversion and exception wrapping.
Apple live session resumption implementation
firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/LiveGenerativeModel.apple.kt, LiveMapper.apple.kt, LiveSession.apple.kt
Implements conditional Swift SDK calls in connect() for session resumption vs. standard connection; maps context compression and session resumption configs to Apple types; handles sessionResumptionUpdate() messages; implements resumeSession() with config conversion and completion-handler wrapping.
Dependency updates and time type migration
firebase-ai/Package.resolved, firebase-analytics/Package.resolved, firebase-app/Package.resolved, firebase-auth/Package.resolved, firebase-firestore/Package.resolved, gradle/libs.versions.toml, firebase-common/src/commonMain/kotlin/dev/ynagai/firebase/Timestamp.kt, firebase-common/src/commonTest/kotlin/dev/ynagai/firebase/TimestampTest.kt
Updates pinned versions for firebase-ios-sdk (12.14.0), firebase-objc-sdk (0.5.0), google-ads-on-device-conversion-ios-sdk (3.6.0), and googleappmeasurement (12.14.0) across multiple lockfiles; bumps gradle AGP to 9.1.1, kotlinx-coroutines to 1.11.0, kotlinx-serialization to 1.11.0; migrates Timestamp time types from kotlinx.datetime to kotlin.time Clock and Instant.
Reference documentation
firebase-ai/CLAUDE.md
Documents new Tool.GoogleMaps, RetrievalConfig, LatLng, image generation config types, expanded grounding metadata, context compression config, session resumption config, and SessionResumptionUpdate message type.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • uny/firebase-kotlin-sdk#20: Core live streaming APIs that are extended in this PR with session resumption and context compression support.
  • uny/firebase-kotlin-sdk#8: Establishes Tool/function-calling Android↔Apple mapper plumbing that this PR extends with GoogleMaps tool and retrieval config support.
  • uny/firebase-kotlin-sdk#42: Earlier grounding and tool model additions that this PR extends with Google Maps retrieval support.

🐰 Image configs bloom bright,
Maps ground truth takes flight,
Sessions resume with care,
Firebase AI everywhere! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main objectives of the PR: dependency updates and new firebase-ai API additions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch update-deps-and-firebase-ai-apis

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/Tool.kt (1)

91-94: 💤 Low value

Consider adding range validation for latitude and longitude.

The KDoc documents valid ranges (latitude: -90.0 to +90.0, longitude: -180.0 to +180.0), but the data class performs no runtime validation. Invalid values would be caught downstream by the Firebase SDK, but early validation could provide clearer error messages.

🛡️ Optional validation approach
data class LatLng(
    val latitude: Double,
    val longitude: Double,
) {
    init {
        require(latitude in -90.0..90.0) { "Latitude must be in range [-90.0, +90.0], got: $latitude" }
        require(longitude in -180.0..180.0) { "Longitude must be in range [-180.0, +180.0], got: $longitude" }
    }
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/Tool.kt` around
lines 91 - 94, The LatLng data class currently lacks runtime validation for
latitude/longitude despite the KDoc specifying valid ranges; add an init block
to LatLng that checks latitude is within -90.0..90.0 and longitude within
-180.0..180.0 using require (or similar), and provide clear error messages like
"Latitude must be in range [-90.0, +90.0], got: $latitude" and "Longitude must
be in range [-180.0, +180.0], got: $longitude" to fail fast with helpful
context.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.android.kt`:
- Line 34: In AndroidCandidate.toCommon() (in
GenerateContentResponse.android.kt) remove the non-existent mapping
finishMessage (do not reference candidate.finishMessage) and instead set
finishMessage = null when building the common model; also update GroundingChunk
mapping to construct GoogleMapsGroundingChunk(uri, title, placeId) from
GroundingChunk.maps entries, and ensure AndroidFinishReason.toCommon() includes
the added Android enum cases mapping to the common finishReason equivalents.

In
`@firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/ContextWindowCompressionConfig.kt`:
- Around line 9-21: Add input validation to the data classes so invalid token
counts fail fast: in ContextWindowCompressionConfig and SlidingWindow add init
blocks that check if triggerTokens (in ContextWindowCompressionConfig) or
targetTokens (in SlidingWindow) are non-null and <= 0 and throw an
IllegalArgumentException with a clear message; this ensures the constructors for
ContextWindowCompressionConfig and SlidingWindow validate triggerTokens and
targetTokens respectively and prevent non-positive values from being created.

In
`@firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/SessionResumptionConfig.kt`:
- Around line 8-10: SessionResumptionConfig currently allows handle = "" which
should be rejected; add validation in the data class (SessionResumptionConfig)
so that handle is either null or a non-blank string by adding an init block that
enforces require(handle == null || handle.isNotBlank()) and throws an
IllegalArgumentException for blank values, ensuring only null or non-blank
handles are accepted and forwarded.

---

Nitpick comments:
In `@firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/Tool.kt`:
- Around line 91-94: The LatLng data class currently lacks runtime validation
for latitude/longitude despite the KDoc specifying valid ranges; add an init
block to LatLng that checks latitude is within -90.0..90.0 and longitude within
-180.0..180.0 using require (or similar), and provide clear error messages like
"Latitude must be in range [-90.0, +90.0], got: $latitude" and "Longitude must
be in range [-180.0, +180.0], got: $longitude" to fail fast with helpful
context.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cc78350e-be41-4208-a584-6f0317b460c7

📥 Commits

Reviewing files that changed from the base of the PR and between 44c9563 and 269fdd0.

📒 Files selected for processing (33)
  • firebase-ai/CLAUDE.md
  • firebase-ai/Package.resolved
  • firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.android.kt
  • firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerationConfig.android.kt
  • firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/LiveGenerativeModel.android.kt
  • firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/LiveMapper.android.kt
  • firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/LiveSession.android.kt
  • firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/Tool.android.kt
  • firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.apple.kt
  • firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/GenerationConfig.apple.kt
  • firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/LiveGenerativeModel.apple.kt
  • firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/LiveMapper.apple.kt
  • firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/LiveSession.apple.kt
  • firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/Tool.apple.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/ContextWindowCompressionConfig.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/Enums.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/GenerationConfig.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/GroundingMetadata.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/ImageConfig.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/LiveGenerationConfig.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/LiveGenerativeModel.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/LiveServerMessage.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/LiveSession.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/SessionResumptionConfig.kt
  • firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/Tool.kt
  • firebase-analytics/Package.resolved
  • firebase-app/Package.resolved
  • firebase-auth/Package.resolved
  • firebase-common/src/commonMain/kotlin/dev/ynagai/firebase/Timestamp.kt
  • firebase-common/src/commonTest/kotlin/dev/ynagai/firebase/TimestampTest.kt
  • firebase-firestore/Package.resolved
  • gradle/libs.versions.toml

internal fun AndroidCandidate.toCommon(): Candidate = Candidate(
content = content.toCommon(),
finishReason = finishReason?.toCommon(),
finishMessage = finishMessage,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Search for Android SDK response type usage patterns

echo "=== Checking for FinishReason enum usage ==="
rg -n "AndroidFinishReason\." --type=kotlin -g "**/*android*" -C1

echo -e "\n=== Checking for grounding chunk usage ==="
rg -n "GroundingChunk|GoogleMapsGroundingChunk" --type=kotlin -g "**/*android*" -C2

echo -e "\n=== Checking imports of Android SDK types ==="
rg -n "import.*firebase\.ai\.type\.(Candidate|FinishReason|GroundingChunk)" --type=kotlin -g "**/*android*"

Repository: uny/firebase-kotlin-sdk

Length of output: 6772


🌐 Web query:

Firebase Android AI SDK 34.13.0 finishMessage FinishReason IMAGE_SAFETY UNEXPECTED_TOOL_CALL GoogleMapsGroundingChunk

💡 Result:

In the Firebase Android AI SDK, FinishReason values such as IMAGE_SAFETY and UNEXPECTED_TOOL_CALL are part of recent updates designed to provide granular feedback when model generation stops [1][2][3]. These additions were implemented to better handle complex scenarios, particularly those involving image generation and tool-calling [1][2]. Key details regarding your query: - IMAGE_SAFETY: This FinishReason indicates that the model stopped generating content because it triggered safety filters specifically related to image generation (e.g., policy violations such as graphic violence or prohibited content) [1][2][3]. - UNEXPECTED_TOOL_CALL: This indicates that the model attempted to execute a tool call that was either not authorized, malformed, or contextually inappropriate based on the active tool definitions provided in the request [2][4][5]. This often occurs when a model is prompted to use a tool that is not currently enabled or available in the specific turn of the conversation [4]. - GoogleMapsGroundingChunk: This is a component of the model's groundingMetadata [6]. When enabled, it provides source information (chunks) used by the model to ground its response, such as data retrieved from Google Search or specific grounding services like Google Maps [6]. These FinishReason constants were added to the Firebase AI SDKs to allow developers to programmatically handle these specific stopping conditions, rather than treating them as generic errors or unexpected crashes [1][2]. If you encounter issues where these reasons cause crashes, it is often because the SDK's internal parsing logic requires an update to recognize the newer enum constants [5]. Ensure your project is using the latest version of the Firebase Android SDK to support these types [1][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Extract relevant portions of GenerateContentResponse.android.kt ==="
FILE="firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.android.kt"
nl -ba "$FILE" | sed -n '1,120p'
echo "----"
nl -ba "$FILE" | sed -n '120,220p'
echo "----"

echo "=== Find where Firebase BOM / AI SDK version is pinned (look for 34.13.0) ==="
rg -n "34\.13\.0|firebase-bom|firebase-bom\.|platform\(.*firebase-bom|com\.google\.firebase:firebase-bom|firebase-ai" -S . || true

echo "=== List Gradle files mentioning firebase-bom ==="
fd -e "gradle" -e "gradle.kts" -e "kts" -e "toml" -e "build.gradle" . 2>/dev/null | head -n 50 || true
rg -n "firebase-bom" -S . --glob='*.gradle*' --glob='*.kts' || true

Repository: uny/firebase-kotlin-sdk

Length of output: 200


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Extract relevant portions of GenerateContentResponse.android.kt ==="
FILE="firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.android.kt"
nl -ba "$FILE" | sed -n '1,120p'
echo "----"
nl -ba "$FILE" | sed -n '120,220p'
echo "----"

echo "=== Find where Firebase BOM / AI SDK version is pinned (look for 34.13.0) ==="
rg -n "34\.13\.0|firebase-bom|firebase-bom\.|platform\(.*firebase-bom|com\.google\.firebase:firebase-bom|firebase-ai" -S . || true

echo "=== List Gradle files mentioning firebase-bom ==="
fd -e "gradle" -e "gradle.kts" -e "kts" -e "toml" -e "build.gradle" . 2>/dev/null | head -n 50 || true
rg -n "firebase-bom" -S . --glob='*.gradle*' --glob='*.kts' || true

Repository: uny/firebase-kotlin-sdk

Length of output: 200


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.android.kt"

echo "=== Extract relevant portions of GenerateContentResponse.android.kt ==="
echo "--- lines 1-120 ---"
cat -n "$FILE" | sed -n '1,120p'
echo "----"
echo "--- lines 120-240 ---"
cat -n "$FILE" | sed -n '120,240p'

echo "=== Find where Firebase BOM / AI SDK version is pinned (look for 34.13.0) ==="
rg -n "34\.13\.0|firebase-bom|com\.google\.firebase:firebase-bom|firebase-ai|com\.google\.firebase:firebase-ai|firebase-ai:" -S . --hidden || true

echo "=== Search gradle/version catalogs for firebase-bom ==="
rg -n "firebase-bom" -S . --glob='*.gradle*' --glob='*.kts' --hidden || true
rg -n "34\.13\.0" -S . --glob='*.gradle*' --glob='*.kts' --glob='*libs*' --hidden || true

Repository: uny/firebase-kotlin-sdk

Length of output: 12480


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Search for finishMessage usage in firebase-ai android code ==="
rg -n "finishMessage" firebase-ai/src/androidMain -S --glob='*.kt' || true

echo "=== Search for GroundingChunk.maps / GoogleMapsGroundingChunk usage in firebase-ai android code ==="
rg -n "GroundingChunk|GoogleMapsGroundingChunk|\.maps\b" firebase-ai/src/androidMain -S --glob='*.kt' || true

Repository: uny/firebase-kotlin-sdk

Length of output: 1175


🌐 Web query:

com.google.firebase.ai.type.FinishReason IMAGE_SAFETY 34.13.0

💡 Result:

In the Firebase AI SDK, com.google.firebase.ai.type.FinishReason.IMAGE_SAFETY is an enumeration value indicating that the model stopped generating content because the generated image triggered a safety violation [1][2][3]. This reason was introduced as part of an expansion to the FinishReason enum to better support image generation features and complex tool-calling scenarios [1][2]. It is specifically used within the context of the Firebase AI SDK (often associated with BoM version 34.13.0 for Android) when using image generation models, such as the Imagen series [1][4][5]. Key details regarding this finish reason include: - Purpose: It signals that the content generation was halted due to safety filters detecting prohibited or sensitive material within a generated image [2][3]. - SDK Context: It is part of the com.google.firebase.ai.type package [6][7]. The addition was bundled with updates that also introduced support for ImageConfig (including parameters for aspect ratio and size) and several other FinishReason types such as IMAGE_PROHIBITED_CONTENT, IMAGE_OTHER, NO_IMAGE, and IMAGE_RECITATION [1][2][3]. - Usage: When a request to an image generation model is blocked by these safety policies, the SDK returns this IMAGE_SAFETY value to allow developers to handle the failure programmatically [2]. If you are encountering this error, it indicates that the model's output safety guardrails (configured via ImagenSafetySettings) intervened to prevent the rendering of content deemed harmful or inappropriate [8][3][4].

Citations:


🌐 Web query:

com.google.firebase.ai.type.Candidate finishMessage GoogleMapsGroundingChunk GroundingChunk maps uri title placeId

💡 Result:

The GoogleMapsGroundingChunk is a data structure introduced in the Firebase AI SDKs (such as for Android, iOS, Unity, and Web) to represent grounding metadata retrieved from Google Maps [1][2][3][4][5]. It is typically used within the context of a candidate message response when the model employs Google Maps as a grounding tool [1][3]. The chunk provides specific details about a location referenced by the AI model [2][3]. The structure contains three primary properties [2][3]: - uri (String?): The URI of the place [2][3]. - title (String?): The title of the place [2][3]. - placeId (String?): The resource name of the place, formatted as places/{place_id}, which can be used to perform lookups via the Google Maps API [2][4]. As of May 2026, Maps Grounding is part of the broader capabilities of Firebase AI Logic, enabling developers to integrate Google Maps data into AI-generated responses [1][6]. Depending on the platform (e.g., iOS), the implementation may map backend fields differently—for example, mapping the backend uri field to a url property in the Swift SDK [3].

Citations:


🌐 Web query:

com.google.firebase.ai.type.Candidate finishMessage kotlin

💡 Result:

In the Firebase Android SDK, the com.google.firebase.ai.type.Candidate class represents a single response generated by a model [1][2]. While this class contains a finishReason property [1][3], it does not include a finishMessage property. The finishReason property is of type FinishReason (an enum or class representing why generation stopped, such as reaching a limit or being blocked) [1][3]. If you are looking for additional descriptive information regarding why a generation process concluded—especially in the context of error handling or blocking—this information is typically managed via exceptions or response metadata outside of the Candidate class structure [4]. For comparison, while some other SDKs or libraries (such as Genkit's JavaScript implementation) explicitly include a finishMessage property to provide further details on the model's termination [4], the current Firebase Android SDK for Gemini/AI Logic relies on the finishReason for this purpose [1][3].

Citations:


🌐 Web query:

com.google.firebase.ai.type.GroundingChunk maps kotlin

💡 Result:

In Firebase AI Logic (Android Kotlin), com.google.firebase.ai.type.GroundingChunk is a Kotlin class that represents “a chunk of retrieved data that supports a claim in the model's response.” It has a single Kotlin property web: WebGroundingChunk? indicating whether the grounding chunk came from a web source, and it is constructed as GroundingChunk(web: WebGroundingChunk?). [1] How it “maps” in Kotlin (what to read / access) - Type: GroundingChunk (class) [1] - Constructor: GroundingChunk(web: WebGroundingChunk?) [1] - Property: val web: WebGroundingChunk? [1] If you specifically mean “maps grounding” (Google Maps tool), that is represented by a different type: com.google.firebase.ai.type.GoogleMapsGroundingChunk. It has properties uri, title, and placeId (each nullable String?). [2] The GroundingChunk itself is still the wrapper for the retrieved chunk; the maps-specific fields surface via the Grounding metadata as maps/chunk types (e.g., chunk.maps?.title/uri/placeId in the docs example). [3] Example usage pattern from the Firebase docs (reading grounding chunks) - Get grounding metadata from the first candidate’s groundingMetadata, then read groundingChunks, and for each chunk read the source fields (e.g., chunk.maps?.title/uri/placeId for Maps grounding). [3] So the Kotlin mapping is: - GroundingChunk (wrapper) -> web: WebGroundingChunk? (web source details) [1] - Maps source details come through GoogleMapsGroundingChunk fields when using Grounding with Google Maps (uri/title/placeId). [2][3]

Citations:


🌐 Web query:

com.google.firebase.ai.type.GoogleMapsGroundingChunk uri title placeId kotlin

💡 Result:

GoogleMapsGroundingChunk (Firebase AI Logic / Maps grounding) in Kotlin has the properties uri, title, and placeId (all nullable Strings in the Kotlin reference). [1] - uri: The URI of the place. [1] - title: The title of the place. [1] - placeId: This Place’s resource name in the form places/{place_id}. This can be used to look up the place using the Google Maps API. [1] In the Kotlin API reference, the primary constructor is: GoogleMapsGroundingChunk(uri: String?, title: String?, placeId: String?) [1] Example usage note (from the Firebase “Grounding google maps” page): the model response includes groundingChunks entries containing maps fields uri, title, and placeId (placeId is shown like places/ChIJ...). [2]

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "finishMessage" -S . --glob='*.kt' --glob='*.kts' --glob='*.md' || true

Repository: uny/firebase-kotlin-sdk

Length of output: 459


🌐 Web query:

"finishMessage" "com.google.firebase.ai.type.Candidate" kotlin property

💡 Result:

The property finishMessage is not present in the com.google.firebase.ai.type.Candidate class within the Firebase Android SDK [1][2]. While a finishMessage property exists in the Candidate class for the Firebase AI Dart/Flutter SDK [3], the corresponding Kotlin class in the Firebase Android SDK (com.google.firebase.ai.type.Candidate) provides a finishReason property [1] (of type FinishReason? [1]), but does not define a finishMessage property [1]. The Firebase Android SDK release notes for version 17.12.0 mention the addition of support for finishMessage [4], however, technical documentation and class definitions for the current Firebase AI Logic (firebase-ai) SDK indicate that the Kotlin class Candidate primarily exposes finishReason, content, and various metadata properties like citationMetadata and groundingMetadata [1]. If you are encountering a reference to finishMessage in a Kotlin context, it may be a naming confusion with the Dart SDK [3], a very recent addition not yet reflected in standard public API reference documentation, or a misunderstanding of the API structure [1].

Citations:


🌐 Web query:

"val maps" "com.google.firebase.ai.type.GroundingChunk" kotlin

💡 Result:

In Firebase (Kotlin), GroundingChunk is a class that represents a chunk of retrieved data supporting a claim in the model response; it has a nullable web property: val web: WebGroundingChunk?. [1] For “val maps”: in the official Kotlin reference page returned for GroundingChunk, I only see val web and no val maps property. [1] In contrast, the JavaScript reference for GroundingChunk explicitly documents a maps?: GoogleMapsGroundingChunk property. [2] So for your specific query (“val maps” + “com.google.firebase.ai.type.GroundingChunk” + Kotlin): the authoritative Kotlin reference I found does not list a val maps property on GroundingChunk—only val web is shown. [1] If you’re seeing a maps field in your code, it may be from a different SDK language/version (e.g., JS) or a newer/alternate API surface than the page I located. [2]

Citations:


🌐 Web query:

"GroundingChunk" "maps" site:firebase.google.com/docs/reference/kotlin/com/google/firebase/ai/type

💡 Result:

The GoogleMapsGroundingChunk is a data structure used in the Firebase SDKs (specifically for Android) to represent grounding information derived from Google Maps [1]. It is part of the framework's AI type system for handling model responses that include grounded entities [1][2]. This class provides three primary pieces of information regarding a location: - placeId: The resource name of the place in a places/{place_id} format, which can be used for further lookups via the Google Maps API [1]. - title: The name or title of the place [1]. - uri: A URI link associated with the place [1]. Essentially, when an AI model provides a response grounded in real-world data, the GoogleMapsGroundingChunk serves as the object that encapsulates map-specific location details, allowing developers to programmatically access and display location data linked to the model's output [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== GenerateContentResponse.kt (common) around Candidate.finishMessage ==="
FILE="firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.kt"
cat -n "$FILE" | sed -n '1,120p'

echo "=== GenerateContentResponse.apple.kt (apple) around finishMessage mapping ==="
FILE="firebase-ai/src/appleMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.apple.kt"
cat -n "$FILE" | sed -n '1,120p'

Repository: uny/firebase-kotlin-sdk

Length of output: 12229


🌐 Web query:

site:firebase.google.com/docs/reference/kotlin/com/google/firebase/ai/type/Candidate finishMessage

💡 Result:

In the Firebase Android (Kotlin) SDK, com.google.firebase.ai.type.Candidate does not have a finishMessage property—its stop information is exposed via finishReason: FinishReason? (plus properties like content, citationMetadata, safetyRatings, etc.). (firebase.google.com)

finishMessage?: string exists in the Firebase JavaScript API type GenerateContentCandidate, but it’s not part of the Kotlin Candidate reference you linked. (firebase.google.com)

Citations:


🌐 Web query:

site:firebase.google.com/docs/reference/kotlin/com/google/firebase/ai/type/GroundingChunk maps

💡 Result:

In the Firebase Android Kotlin reference for com.google.firebase.ai.type.GroundingChunk, maps is a nullable property:

  • val maps: GoogleMapsGroundingChunk?
  • It “contains details if the grounding chunk is from a Google Maps source.” [1]

Constructor: GroundingChunk(web: WebGroundingChunk? = null, maps: GoogleMapsGroundingChunk? = null) [1]

Source(s):
[1] (firebase.google.com)

Citations:


🌐 Web query:

site:firebase.google.cn/docs/reference/kotlin/com/google/firebase/ai/type/Candidate finishMessage

💡 Result:

In the Firebase AI Kotlin reference, com.google.firebase.ai.type.Candidate does not have a finishMessage property—it exposes finishReason (plus content, safetyRatings, etc.) instead. [1]

finishMessage exists in other Firebase AI surfaces (for example the JavaScript GenerateContentCandidate.finishMessage and the REST GenerateContentResponse schema), but it’s not part of the Kotlin Candidate API. [2][3]


🌐 Web query:

site:firebase.google.cn/docs/reference/kotlin/com/google/firebase/ai/type/GroundingChunk maps

💡 Result:

In the Firebase Android Kotlin API reference, com.google.firebase.ai.type.GroundingChunk includes a maps field:

  • Constructor: GroundingChunk(web: WebGroundingChunk? = null, maps: GoogleMapsGroundingChunk? = null)
  • Property: val maps: GoogleMapsGroundingChunk? — “Contains details if the grounding chunk is from a Google Maps source.”
    It also has val web: WebGroundingChunk? for web-based grounding. [1]

Sources
[1] (firebase.google.com)

Citations:


Fix Android Candidate.finishMessage mapping

AndroidCandidate.toCommon() sets finishMessage = finishMessage, but com.google.firebase.ai.type.Candidate in the Firebase Android AI SDK doesn’t expose a finishMessage property (it only provides finishReason and other metadata). Update the Android mapping to drop this field or set it to null (around line 34 in GenerateContentResponse.android.kt).

GroundingChunk.mapsGoogleMapsGroundingChunk(uri, title, placeId) and the added AndroidFinishReason enum cases mapped in AndroidFinishReason.toCommon() are consistent with the Android SDK types (around lines 70-91 and 146-155).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@firebase-ai/src/androidMain/kotlin/dev/ynagai/firebase/ai/GenerateContentResponse.android.kt`
at line 34, In AndroidCandidate.toCommon() (in
GenerateContentResponse.android.kt) remove the non-existent mapping
finishMessage (do not reference candidate.finishMessage) and instead set
finishMessage = null when building the common model; also update GroundingChunk
mapping to construct GoogleMapsGroundingChunk(uri, title, placeId) from
GroundingChunk.maps entries, and ensure AndroidFinishReason.toCommon() includes
the added Android enum cases mapping to the common finishReason equivalents.

Comment on lines +9 to +21
data class ContextWindowCompressionConfig(
val triggerTokens: Int? = null,
val slidingWindow: SlidingWindow? = null,
)

/**
* Configures the sliding window context compression mechanism.
*
* @property targetTokens The session reduction target — how many tokens to keep.
*/
data class SlidingWindow(
val targetTokens: Int? = null,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate token counts at construction time.

triggerTokens and targetTokens currently accept non-positive values. Failing fast here prevents invalid configs from reaching platform SDK calls.

Suggested fix
 data class ContextWindowCompressionConfig(
     val triggerTokens: Int? = null,
     val slidingWindow: SlidingWindow? = null,
-)
+) {
+    init {
+        require(triggerTokens == null || triggerTokens > 0) {
+            "triggerTokens must be > 0"
+        }
+    }
+}
@@
 data class SlidingWindow(
     val targetTokens: Int? = null,
-)
+) {
+    init {
+        require(targetTokens == null || targetTokens > 0) {
+            "targetTokens must be > 0"
+        }
+    }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
data class ContextWindowCompressionConfig(
val triggerTokens: Int? = null,
val slidingWindow: SlidingWindow? = null,
)
/**
* Configures the sliding window context compression mechanism.
*
* @property targetTokens The session reduction target — how many tokens to keep.
*/
data class SlidingWindow(
val targetTokens: Int? = null,
)
data class ContextWindowCompressionConfig(
val triggerTokens: Int? = null,
val slidingWindow: SlidingWindow? = null,
) {
init {
require(triggerTokens == null || triggerTokens > 0) {
"triggerTokens must be > 0"
}
}
}
/**
* Configures the sliding window context compression mechanism.
*
* `@property` targetTokens The session reduction target — how many tokens to keep.
*/
data class SlidingWindow(
val targetTokens: Int? = null,
) {
init {
require(targetTokens == null || targetTokens > 0) {
"targetTokens must be > 0"
}
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/ContextWindowCompressionConfig.kt`
around lines 9 - 21, Add input validation to the data classes so invalid token
counts fail fast: in ContextWindowCompressionConfig and SlidingWindow add init
blocks that check if triggerTokens (in ContextWindowCompressionConfig) or
targetTokens (in SlidingWindow) are non-null and <= 0 and throw an
IllegalArgumentException with a clear message; this ensures the constructors for
ContextWindowCompressionConfig and SlidingWindow validate triggerTokens and
targetTokens respectively and prevent non-positive values from being created.

Comment on lines +8 to +10
data class SessionResumptionConfig(
val handle: String? = null,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reject blank session handles.

Line 9 allows handle = "", which will still be forwarded as a provided handle. Add a guard so only null or non-blank values are accepted.

Suggested fix
 data class SessionResumptionConfig(
     val handle: String? = null,
-)
+) {
+    init {
+        require(handle == null || handle.isNotBlank()) {
+            "handle must be null or non-blank"
+        }
+    }
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@firebase-ai/src/commonMain/kotlin/dev/ynagai/firebase/ai/SessionResumptionConfig.kt`
around lines 8 - 10, SessionResumptionConfig currently allows handle = "" which
should be rejected; add validation in the data class (SessionResumptionConfig)
so that handle is either null or a non-blank string by adding an init block that
enforces require(handle == null || handle.isNotBlank()) and throws an
IllegalArgumentException for blank values, ensuring only null or non-blank
handles are accepted and forwarded.

uny and others added 2 commits May 28, 2026 09:27
…m properties

- Fix Android resumeSession() passing null to non-nullable SDK overload
- Remove unused kotlinx-datetime dependency (migrated to kotlin.time)
- Remove dead AspectRatio.value and ImageSize.value properties

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@uny
uny merged commit 7e2c0cb into main May 28, 2026
3 checks passed
@uny
uny deleted the update-deps-and-firebase-ai-apis branch May 28, 2026 00:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.