Skip to content

Commit

Permalink
Add Vertex AI for Firebase quickstart (#1610)
Browse files Browse the repository at this point in the history
* feat: add vertexai quickstart app

* style: run ktlint

* chore: add vertex ai to mock-google-services.json

* add Vertex AI link to main README file

* bump gradle to 8.6

* Remove properties not supported by java 17 (#1612)

* Update model to 1.5-pro (#1611)

---------

Co-authored-by: Rodrigo Lazo <[email protected]>
  • Loading branch information
thatfiredev and rlazo committed May 13, 2024
1 parent af96c6d commit 2edbc52
Show file tree
Hide file tree
Showing 55 changed files with 2,873 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ the sample you wish to run.
- [ML Kit Translate](mlkit-translate/README.md)
- [Performance Monitoring](perf/README.md)
- [Storage](storage/README.md)
- [Vertex AI](vertexai/README.md)

## How to make contributions?
Please read and follow the steps in the [CONTRIBUTING.md](CONTRIBUTING.md)
Expand Down
1 change: 1 addition & 0 deletions copy_mock_google_services_json.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ cp mock-google-services.json inappmessaging/app/google-services.json
cp mock-google-services.json perf/app/google-services.json
cp mock-google-services.json messaging/app/google-services.json
cp mock-google-services.json storage/app/google-services.json
cp mock-google-services.json vertexai/app/google-services.json
19 changes: 19 additions & 0 deletions mock-google-services.json
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,25 @@
"test_interstitial_ad_unit_id": "ca-app-pub-3940256099942544/1033173712"
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:474448463284:android:c76572afd2f0ba8d97e8e1",
"android_client_info": {
"package_name": "com.google.firebase.quickstart.vertexai"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyCPndbsEs_QWumL5_B0BpNLuMkvVSecvL0"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"client_info": [],
Expand Down
3 changes: 2 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ include(":admob:app",
":inappmessaging:app",
":messaging:app",
":perf:app",
":storage:app"
":storage:app",
":vertexai:app"
)
30 changes: 30 additions & 0 deletions vertexai/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Firebase Vertex AI Sample for Android (Kotlin)

This Android sample app demonstrates how to use state-of-the-art
generative AI models (like Gemini) to build AI-powered features and applications.

To try out this sample app, you need to use latest stable version of Android Studio.
However, if you want to latest lint checks and AI productivity features in Android
Studio use the latest preview version of [Android Studio](https://developer.android.com/studio/preview).

You can clone this repository or import the project from Android Studio following the steps
[here](https://developer.android.com/jetpack/compose/setup#sample).

## Screenshots

<img src="screenshots/screenshots.png" alt="Screenshot">

## Requirements

TODO

## Features

This sample showcases the following API capablilites:
* Generate Text - demonstrates the Text feature from the SDK
* Photo Reasoning - demonstrates the MultiModal feature from the SDK
* Chat - demonstrates the Multi-turn Conversations feature from the SDK

## Documentation

TODO
79 changes: 79 additions & 0 deletions vertexai/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.gms.google-services")
}

android {
namespace = "com.google.firebase.quickstart.vertexai"
compileSdk = 34

defaultConfig {
applicationId = "com.google.firebase.quickstart.vertexai"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.13"
}
}

dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2")
implementation("androidx.activity:activity-compose:1.8.1")
implementation("androidx.navigation:navigation-compose:2.7.5")

implementation(platform("androidx.compose:compose-bom:2023.10.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")

implementation("io.coil-kt:coil-compose:2.5.0")
implementation("com.google.firebase:firebase-analytics:21.6.1")
implementation("com.google.firebase:firebase-vertexai:16.0.0-alpha03")

testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
40 changes: 40 additions & 0 deletions vertexai/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2023 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.firebase.quickstart.vertexai

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.CreationExtras
import com.google.firebase.Firebase
import com.google.firebase.quickstart.vertexai.feature.chat.ChatViewModel
import com.google.firebase.quickstart.vertexai.feature.functioncalling.FunctionsChatViewModel
import com.google.firebase.quickstart.vertexai.feature.multimodal.PhotoReasoningViewModel
import com.google.firebase.quickstart.vertexai.feature.text.SummarizeViewModel
import com.google.firebase.vertexai.type.Schema
import com.google.firebase.vertexai.type.Tool
import com.google.firebase.vertexai.type.defineFunction
import com.google.firebase.vertexai.type.generationConfig
import com.google.firebase.vertexai.vertexAI
import org.json.JSONObject

val GenerativeViewModelFactory = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(
viewModelClass: Class<T>,
extras: CreationExtras
): T {
val config = generationConfig {
temperature = 0.7f
}

return with(viewModelClass) {
when {
isAssignableFrom(SummarizeViewModel::class.java) -> {
// Initialize a GenerativeModel with the `gemini-pro` AI model
// for text generation
val generativeModel = Firebase.vertexAI.generativeModel(
modelName = "gemini-1.5-pro-preview-0409",
generationConfig = config
)
SummarizeViewModel(generativeModel)
}

isAssignableFrom(PhotoReasoningViewModel::class.java) -> {
// Initialize a GenerativeModel with the `gemini-pro` AI model
// for multimodal text generation
val generativeModel = Firebase.vertexAI.generativeModel(
modelName = "gemini-1.5-pro-preview-0409",
generationConfig = config
)
PhotoReasoningViewModel(generativeModel)
}

isAssignableFrom(ChatViewModel::class.java) -> {
// Initialize a GenerativeModel with the `gemini-pro` AI model for chat
val generativeModel = Firebase.vertexAI.generativeModel(
modelName = "gemini-1.5-pro-preview-0409",
generationConfig = config
)
ChatViewModel(generativeModel)
}

isAssignableFrom(FunctionsChatViewModel::class.java) -> {
// Declare the functions you want to make available to the model
val tools = listOf(
Tool(
listOf(
defineFunction(
"upperCase",
"Returns the upper case version of the input string",
Schema.str("input", "Text to transform")
) { input ->
JSONObject("{\"response\": \"${input.uppercase()}\"}")
}
)
)
)

// Initialize a GenerativeModel with the `gemini-pro` AI model for function calling chat
val generativeModel = Firebase.vertexAI.generativeModel(
modelName = "gemini-1.5-pro-preview-0409",
generationConfig = config,
tools = tools
)
FunctionsChatViewModel(generativeModel)
}

else ->
throw IllegalArgumentException("Unknown ViewModel class: ${viewModelClass.name}")
}
} as T
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.firebase.quickstart.vertexai

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.google.firebase.quickstart.vertexai.feature.chat.ChatRoute
import com.google.firebase.quickstart.vertexai.feature.functioncalling.FunctionsChatRoute
import com.google.firebase.quickstart.vertexai.feature.multimodal.PhotoReasoningRoute
import com.google.firebase.quickstart.vertexai.feature.text.SummarizeRoute
import com.google.firebase.quickstart.vertexai.ui.theme.GenerativeAISample

class MainActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
GenerativeAISample {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "menu") {
composable("menu") {
MenuScreen(onItemClicked = { routeId ->
navController.navigate(routeId)
})
}
composable("summarize") {
SummarizeRoute()
}
composable("photo_reasoning") {
PhotoReasoningRoute()
}
composable("chat") {
ChatRoute()
}
composable("functions_chat") {
FunctionsChatRoute()
}
}
}
}
}
}
}
Loading

0 comments on commit 2edbc52

Please sign in to comment.