Skip to content

Add hybrid SDK sample#153

Draft
lethargicpanda wants to merge 1 commit intomainfrom
te/hybrid-review
Draft

Add hybrid SDK sample#153
lethargicpanda wants to merge 1 commit intomainfrom
te/hybrid-review

Conversation

@lethargicpanda
Copy link
Collaborator

No description provided.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request integrates a new 'Gemini Hybrid' sample into the AI Sample Catalog. The sample is designed to illustrate how to leverage both on-device and cloud-based Gemini models for generative AI tasks, specifically for generating and translating hotel reviews. It provides a practical example of implementing a robust AI solution that can adapt to different device capabilities and network conditions by intelligently switching between local and remote inference.

Highlights

  • New Hybrid AI Sample Added: A new sample application, 'Gemini Hybrid', has been introduced to demonstrate a hybrid approach to generative AI inference. This sample showcases the use of both on-device (Gemini Nano via ML Kit) and cloud-based (Gemini Flash via Firebase AI SDK) models, with a fallback mechanism to the cloud when on-device capabilities are unavailable or for more complex tasks.
  • Hybrid Inference Capabilities: The sample allows users to generate hotel reviews based on selected topics and then translate them into various languages. It provides options to choose different inference modes (e.g., only on-device, only in cloud, prefer on-device, prefer in cloud) to observe the behavior of hybrid model deployment.
  • Dependency Updates: New Firebase AI on-device dependencies (firebase-ai-ondevice and firebase-ai-ondevice-interop) have been added to libs.versions.toml to support the hybrid inference functionality.
  • UI and ViewModel Implementation: The new sample includes a complete Compose UI (GeminiHybridScreen.kt) for user interaction and a ViewModel (GeminiHybridViewModel.kt) to manage the application logic, state, and interaction with the Firebase AI SDK for both generation and translation tasks.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • app/build.gradle.kts
    • Added a project dependency for the new 'gemini-hybrid' sample.
  • app/src/main/java/com/android/ai/catalog/domain/SampleCatalog.kt
    • Imported the new GeminiHybridScreen.
    • Opted into PublicPreviewAPI for the sampleCatalog.
    • Added a new SampleCatalogItem entry for the Gemini Hybrid sample, including its title, description, route, entry screen, tags, and Firebase requirement.
  • app/src/main/res/values/strings.xml
    • Added new string resources for the Gemini Hybrid sample's title and description.
  • gradle/libs.versions.toml
    • Added a new version reference for firebaseAiOndevice.
    • Added new library definitions for firebase-ai-ondevice and firebase-ai-ondevice-interop.
    • Updated the firebase-ai library definition to use a version reference.
  • samples/gemini-hybrid/.gitignore
    • Added a .gitignore file to exclude build artifacts.
  • samples/gemini-hybrid/README.md
    • Added a README file detailing the Gemini Hybrid sample's description, how it works, and key code snippets for on-device and cloud inference.
  • samples/gemini-hybrid/build.gradle.kts
    • Added a new Gradle build file for the 'gemini-hybrid' module, configuring Android library settings, dependencies (including Firebase AI, ML Kit, and Compose), and Kotlin options.
  • samples/gemini-hybrid/consumer-rules.pro
    • Added an empty consumer-rules.pro file.
  • samples/gemini-hybrid/proguard-rules.pro
    • Added a proguard-rules.pro file with standard ProGuard comments.
  • samples/gemini-hybrid/src/main/java/com/android/ai/samples/geminihybrid/GeminiHybridScreen.kt
    • Added the Compose UI screen for the Gemini Hybrid sample, including components for topic selection, inference mode dropdown, review generation, translation, and status display.
  • samples/gemini-hybrid/src/main/java/com/android/ai/samples/geminihybrid/GeminiHybridViewModel.kt
    • Added the ViewModel for the Gemini Hybrid sample, managing UI state, inference mode, selected tags, review text, and implementing the logic for generating and translating content using Firebase AI SDK.
  • samples/gemini-hybrid/src/main/res/values/strings.xml
    • Added specific string resources for the Gemini Hybrid sample, including titles, descriptions, button texts, language options, status messages, and review topics.
  • settings.gradle.kts
    • Included the new ':samples:gemini-hybrid' project in the build.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@lethargicpanda lethargicpanda marked this pull request as draft February 27, 2026 17:21
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new 'Gemini Hybrid' sample, demonstrating a hybrid approach with on-device and cloud-based models. The implementation is well-structured within the new module, utilizing a ViewModel and Jetpack Compose for the UI.

My review focuses on adherence to the repository's architecture guidelines, code consistency, and maintainability. Key feedback includes suggestions to align with the recommended layered architecture, improve composable function signatures for better reusability, and correct some inconsistencies in the build configuration and documentation. Addressing these points will enhance the quality and clarity of the new sample.

Comment on lines +11 to +28
The application first attempts to perform a task (e.g., summarization) using the on-device Gemini Nano model through the ML Kit GenAI API. If the model is not supported on the device or fails to download, it seamlessly falls back to the Gemini Flash model in the cloud using the Firebase AI SDK.

### Key Snippets

#### On-Device Inference (ML Kit)
```kotlin
val summarizer = Summarization.getClient(options)
val featureStatus = summarizer.checkFeatureStatus().await()
if (featureStatus == FeatureStatus.READY) {
summarizer.runInference(request) { ... }.await()
}
```

#### Cloud Inference (Firebase AI)
```kotlin
val generativeModel = Firebase.ai.generativeModel("gemini-1.5-flash")
val response = generativeModel.generateContent(prompt)
```
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The description and code snippets in this README do not match the actual implementation in the sample. The README describes using the ML Kit GenAI API (Summarization.getClient), but the code uses the Firebase AI Hybrid SDK (Firebase.ai.generativeModel).

This discrepancy can be very confusing for developers trying to understand the sample. Please update the README to accurately reflect the code's implementation and provide correct code snippets.

This is related to the style guide recommendation to keep documentation aligned with the code.

References
  1. When a view model or the business logic is modified in the code of a sample, verify that these changes are properly reflected in the README.md of this sample. (link)

_selectedLanguage.value = language
}

fun generateReview(tagStrings: List<String>) {
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The business logic for interacting with the Firebase AI SDK is implemented directly within the GeminiHybridViewModel. The repository's architecture guidelines strongly recommend separating concerns by placing data-sourcing logic in a dedicated data layer, exposed to the ViewModel via a repository.

Refactoring this logic into a GeminiHybridRepository would better align with the recommended architecture, improving testability and maintainability.

References
  1. The data layer should expose data via a repository. UI components (composables, activities, ViewModels) should not interact directly with data sources (databases, DataStore, network, etc.). (link)


android {
namespace = "com.android.ai.samples.geminihybrid"
compileSdk = 35
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The compileSdk version is set to 35, which is inconsistent with the main app module that uses version 36. To ensure consistency across the project and avoid potential build issues, it's recommended to use the same compileSdk version.

    compileSdk = 36

Comment on lines +67 to +68
implementation(libs.genai.summarization)
implementation(libs.kotlinx.coroutines.guava)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

These dependencies (genai.summarization and kotlinx.coroutines.guava) appear to be unused in the gemini-hybrid module. The implementation uses the Firebase AI SDK directly, not the ML Kit Summarization API. To keep the module clean and avoid unnecessary dependencies, these lines should be removed.


@OptIn(ExperimentalLayoutApi::class)
@Composable
fun InitialReviewUi(
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The composable function InitialReviewUi is missing a Modifier parameter. According to the architecture guidelines, all composables (except top-level screens) should accept a Modifier as the first optional parameter. This improves flexibility, allowing the caller to customize layout, appearance, and behavior.

This applies to other composables in this file as well: GeneratingUi, SuccessReviewUi, ErrorUi, LanguageDropdown, InferenceModeDropdown, and StatusText.

Suggested change
fun InitialReviewUi(
fun InitialReviewUi(
modifier: Modifier = Modifier,
References
  1. Every composable function (except top level screen composable) should take a Modifier as a parameter with a default value. It should be positionned as the first optional parameter. (link)

Comment on lines +134 to +146
_uiState.update { state ->
if (state is GeminiHybridUiState.Generating) {
state.copy(
isCloud = isCloud,
partialOutput = state.partialOutput + (chunk.text ?: "")
)
} else {
GeminiHybridUiState.Generating(
isCloud = isCloud,
partialOutput = chunk.text ?: "",
isTranslation = false
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic for updating the UI state while the content stream is being collected is duplicated in generateReview and translate (lines 193-205). This makes the code harder to maintain.

Consider extracting this state update logic into a private helper function to reduce duplication and improve readability.

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