Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions jetpacker/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ export/

# Generated third-party notices
THIRD_PARTY_NOTICES

# Python files
**/__pycache__/
*.pyc

1 change: 1 addition & 0 deletions jetpacker/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ If you wish to run, explore, or modify the code locally:
1. Clone the repository:
```bash
git clone https://github.com/android/ai-samples.git
cd ai-samples/jetpacker
```
2. Open the project in Android Studio.
3. Gradle will automatically sync and resolve dependencies.
Expand Down
25 changes: 24 additions & 1 deletion jetpacker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
</table>

## Overview
JetPacker provides users with powerful tools to manage their upcoming trips, build out rich itineraries, record voice notes, manage travel expenses, generate on-device "Trip Summaries and Tips", generate AI reviews, chat with hotel staff via automatic translation, get real-time museum assistant guidance, and contribute to Android's intelligence system with trip management functions through [AppFunctions](https://d.android.com/ai/appfunctions).
JetPacker provides users with powerful tools to manage their upcoming trips, build out rich itineraries, record voice notes, manage travel expenses, generate on-device "Trip Summaries and Tips", generate AI reviews, chat with hotel staff via automatic translation, get real-time museum assistant guidance, coordinate reservations with an AI Booking Assistant using Jetpack A2UI, and contribute to Android's intelligence system with trip management functions through [AppFunctions](https://d.android.com/ai/appfunctions).

## Architecture
This project is built using modern Android architecture components:
- **UI**: Jetpack Compose
- **Agent-Driven UI**: Jetpack A2UI (`androidx.a2ui`) Compose renderer
- **Dependency Injection**: Dagger/Hilt
- **Local Persistence**: Room Database
- **State Management**: ViewModels with StateFlow
Expand Down Expand Up @@ -50,6 +51,7 @@ JetPacker follows a clean, multi-module Android structure organized by responsib
- **`:feature:trip:itinerary:enrichment`**: On-device AI summaries and tips (`TripSummaryAndTipsCard`) and dynamic daily theme generators.
- **`:feature:trip:expenses`**: Expense tracking screen and automated receipt parser.
- **`:feature:trip:voice_notes`**: Audio voice note recorder and real-time speech-to-text transcription screen.
- **`:feature:trip:booking_assistant`**: Booking Assistant interactive agent interface rendered with Jetpack A2UI.

## Getting Started

Expand Down Expand Up @@ -92,6 +94,26 @@ cd android
./gradlew test
```

### Running the Booking Assistant Server
JetPacker uses a Python-based Server-Sent Events (SSE) server powered by Google ADK to coordinate the booking agents. To run the booking assistant backend locally:

```bash
# Navigate to the server directory
cd server

# Install dependencies
pip install -r requirements.txt

# Run the server
uvicorn main:app --host 0.0.0.0 --port 8000
```

Alternatively, run with Docker:
```bash
docker build -t jetpacker-server .
docker run -p 8080:8080 jetpacker-server
```

## On-Device AI Features
JetPacker integrates local on-device AI capabilities using ML Kit. These features run entirely on-device and can be toggled or customized in `android/core/flags/src/main/kotlin/com/example/jetpacker/core/flags/FeatureFlags.kt`:
- **ENABLE_TRIP_SUMMARY_AND_TIPS**: Generates an on-device card summary of the current trip using ML Kit GenAI Prompt.
Expand All @@ -104,6 +126,7 @@ JetPacker also integrates online hybrid features using Firebase AI Logic (Gemini
- **ENABLE_MUSEUM_ASSISTANT**: Museum Assistant chatbot with URL, Maps, and Search grounding (uses Gemini 3.5 flash-lite).
- **ENABLE_REVIEW_GENERATION**: Topic-selected review generator (uses Gemini 3.5 flash-lite on-device with cloud fallback).
- **Hotel Support Chat**: Receives hotel receptionist assistance with real-time ML Kit + Gemini translation.
- **Booking Assistant**: Parallel multi-agent travel coordinator providing dynamic interactive booking cards rendered via Jetpack A2UI with Cloud Run SSE backend streaming.

## AppFunctions Integration
JetPacker uses Android's [**AppFunctions**](https://d.android.com/ai/appfunctions) library (`androidx.appfunctions`) in `:feature:appfunctions` to contribute to Android's intelligence system with structured travel actions and data queries via `JetPackerAppFunctionService`:
Expand Down
14 changes: 7 additions & 7 deletions jetpacker/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* limitations under the License.
*/


plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.compose)
Expand All @@ -28,9 +27,10 @@ plugins {
android {
namespace = "com.example.jetpacker"
compileSdk {
version = release(libs.versions.compileSdk.get().toInt()) {
minorApiLevel = libs.versions.compileSdkMinor.get().toInt()
}
version =
release(libs.versions.compileSdk.get().toInt()) {
minorApiLevel = libs.versions.compileSdkMinor.get().toInt()
}
}

defaultConfig {
Expand Down Expand Up @@ -61,9 +61,7 @@ android {
}

packaging {
jniLibs {
useLegacyPackaging = false
}
jniLibs { useLegacyPackaging = false }
resources {
excludes += "META-INF/DEPENDENCIES"
excludes += "META-INF/LICENSE"
Expand Down Expand Up @@ -92,6 +90,7 @@ dependencies {
implementation(project(":data:itinerary"))
implementation(project(":data:trips"))
implementation(project(":feature:appfunctions"))
implementation(libs.androidx.appfunctions)
implementation(project(":feature:create_trip"))
implementation(project(":feature:detail"))
implementation(project(":feature:detail:museum_assistant"))
Expand All @@ -104,6 +103,7 @@ dependencies {
implementation(project(":feature:trip:voice_notes"))
implementation(project(":feature:trip:expenses"))
implementation(project(":feature:trip:itinerary:enrichment"))
implementation(project(":feature:trip:booking_assistant"))
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.camera.camera2)
implementation(libs.androidx.camera.core)
Expand Down
2 changes: 1 addition & 1 deletion jetpacker/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.JetPacker"
android:usesCleartextTraffic="false">
android:usesCleartextTraffic="true">
<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object FeatureFlags {
const val KEY_ENABLE_MUSEUM_ASSISTANT = "enable_museum_assistant"
const val KEY_ENABLE_URL_GROUNDING = "enable_url_grounding"
const val KEY_ENABLE_SEARCH_GROUNDING = "enable_search_grounding"
const val KEY_ENABLE_BOOKING_ASSISTANT = "enable_booking_assistant"

private var appContext: Context? = null

Expand Down Expand Up @@ -87,6 +88,10 @@ object FeatureFlags {

val ENABLE_SEARCH_GROUNDING: Boolean
get() = readFlag(KEY_ENABLE_SEARCH_GROUNDING, true)

val ENABLE_BOOKING_ASSISTANT: Boolean
get() = readFlag(KEY_ENABLE_BOOKING_ASSISTANT, true)

private fun readLongFlag(keyName: String, defaultValue: Long): Long {
val context = appContext ?: return defaultValue
return context
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2026 The Android Open Source Project
*
* 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 {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.hilt.android)
alias(libs.plugins.google.devtools.ksp)
}

android {
namespace = "com.example.jetpacker.feature.booking_assistant"
compileSdk = libs.versions.compileSdk.get().toInt()
defaultConfig { minSdk = libs.versions.minSdk.get().toInt() }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures { compose = true }
}

dependencies {
implementation(libs.androidx.core.ktx)
implementation(project(":core:ui"))
implementation(project(":core:flags"))
implementation(project(":data:itinerary"))
implementation(project(":data:trips"))

implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material.icons.core)
implementation(libs.androidx.compose.material.icons.extended)
implementation(libs.androidx.compose.ui.tooling.preview)
debugImplementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.hilt.navigation.compose)
implementation(libs.hilt.android)
"ksp"(libs.hilt.compiler)

// A2UI Compose Renderer (Jetpack snapshot build 16368166)
implementation(libs.androidx.a2ui.model)
implementation(libs.androidx.a2ui.compose.runtime)
implementation(libs.androidx.a2ui.compose.ui)
implementation(libs.androidx.compose.material3.a2ui)

// Cloud Run backend streaming
implementation(libs.okhttp)
implementation(platform(libs.firebase.bom))
implementation(libs.firebase.auth.ktx)
implementation(libs.kotlinx.coroutines.play.services)
}

kotlin { jvmToolchain(17) }
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2026 The Android Open Source Project

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"
package="com.example.jetpacker.feature.booking_assistant" />
Loading
Loading