Skip to content

Commit db2c052

Browse files
Add booking assistant intelligent feature with Jetpack A2UI
Integrates the Booking Assistant feature into JetPacker: - Adopts official Jetpack A2UI Compose renderer (androidx.a2ui build 16368166) - Implements custom interactive UI catalog (InteractiveOptionPicker, SeatSelectionPicker, BookingStatus) - Groups booking surfaces into collapsible category cards with dynamic action status - Connects to SSE Cloud Run backend coordinator with local dev fallback - Adds Python FastAPI server implementation under jetpacker/server/ with Dockerfile and requirements
1 parent 0790aba commit db2c052

19 files changed

Lines changed: 2763 additions & 14 deletions

File tree

‎jetpacker/.gitignore‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@ export/
2626

2727
# Generated third-party notices
2828
THIRD_PARTY_NOTICES
29+
30+
# Python files
31+
**/__pycache__/
32+
*.pyc
33+

‎jetpacker/CONTRIBUTING.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ If you wish to run, explore, or modify the code locally:
4242
1. Clone the repository:
4343
```bash
4444
git clone https://github.com/android/ai-samples.git
45+
cd ai-samples/jetpacker
4546
```
4647
2. Open the project in Android Studio.
4748
3. Gradle will automatically sync and resolve dependencies.

‎jetpacker/README.md‎

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
</table>
1515

1616
## Overview
17-
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).
17+
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).
1818

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

5456
## Getting Started
5557

@@ -92,6 +94,26 @@ cd android
9294
./gradlew test
9395
```
9496
97+
### Running the Booking Assistant Server
98+
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:
99+
100+
```bash
101+
# Navigate to the server directory
102+
cd server
103+
104+
# Install dependencies
105+
pip install -r requirements.txt
106+
107+
# Run the server
108+
uvicorn main:app --host 0.0.0.0 --port 8000
109+
```
110+
111+
Alternatively, run with Docker:
112+
```bash
113+
docker build -t jetpacker-server .
114+
docker run -p 8080:8080 jetpacker-server
115+
```
116+
95117
## On-Device AI Features
96118
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`:
97119
- **ENABLE_TRIP_SUMMARY_AND_TIPS**: Generates an on-device card summary of the current trip using ML Kit GenAI Prompt.
@@ -104,6 +126,7 @@ JetPacker also integrates online hybrid features using Firebase AI Logic (Gemini
104126
- **ENABLE_MUSEUM_ASSISTANT**: Museum Assistant chatbot with URL, Maps, and Search grounding (uses Gemini 3.5 flash-lite).
105127
- **ENABLE_REVIEW_GENERATION**: Topic-selected review generator (uses Gemini 3.5 flash-lite on-device with cloud fallback).
106128
- **Hotel Support Chat**: Receives hotel receptionist assistance with real-time ML Kit + Gemini translation.
129+
- **Booking Assistant**: Parallel multi-agent travel coordinator providing dynamic interactive booking cards rendered via Jetpack A2UI with Cloud Run SSE backend streaming.
107130
108131
## AppFunctions Integration
109132
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`:

‎jetpacker/android/app/build.gradle.kts‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* limitations under the License.
1515
*/
1616

17-
1817
plugins {
1918
alias(libs.plugins.android.application)
2019
alias(libs.plugins.kotlin.compose)
@@ -28,9 +27,10 @@ plugins {
2827
android {
2928
namespace = "com.example.jetpacker"
3029
compileSdk {
31-
version = release(libs.versions.compileSdk.get().toInt()) {
32-
minorApiLevel = libs.versions.compileSdkMinor.get().toInt()
33-
}
30+
version =
31+
release(libs.versions.compileSdk.get().toInt()) {
32+
minorApiLevel = libs.versions.compileSdkMinor.get().toInt()
33+
}
3434
}
3535

3636
defaultConfig {
@@ -61,9 +61,7 @@ android {
6161
}
6262

6363
packaging {
64-
jniLibs {
65-
useLegacyPackaging = false
66-
}
64+
jniLibs { useLegacyPackaging = false }
6765
resources {
6866
excludes += "META-INF/DEPENDENCIES"
6967
excludes += "META-INF/LICENSE"
@@ -92,6 +90,7 @@ dependencies {
9290
implementation(project(":data:itinerary"))
9391
implementation(project(":data:trips"))
9492
implementation(project(":feature:appfunctions"))
93+
implementation(libs.androidx.appfunctions)
9594
implementation(project(":feature:create_trip"))
9695
implementation(project(":feature:detail"))
9796
implementation(project(":feature:detail:museum_assistant"))
@@ -104,6 +103,7 @@ dependencies {
104103
implementation(project(":feature:trip:voice_notes"))
105104
implementation(project(":feature:trip:expenses"))
106105
implementation(project(":feature:trip:itinerary:enrichment"))
106+
implementation(project(":feature:trip:booking_assistant"))
107107
implementation(libs.androidx.activity.compose)
108108
implementation(libs.androidx.camera.camera2)
109109
implementation(libs.androidx.camera.core)

‎jetpacker/android/app/src/main/AndroidManifest.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
android:label="@string/app_name"
3333
android:supportsRtl="true"
3434
android:theme="@style/Theme.JetPacker"
35-
android:usesCleartextTraffic="false">
35+
android:usesCleartextTraffic="true">
3636
<activity
3737
android:name=".MainActivity"
3838
android:exported="true"

‎jetpacker/android/core/flags/src/main/kotlin/com/example/jetpacker/core/flags/FeatureFlags.kt‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ object FeatureFlags {
3131
const val KEY_ENABLE_MUSEUM_ASSISTANT = "enable_museum_assistant"
3232
const val KEY_ENABLE_URL_GROUNDING = "enable_url_grounding"
3333
const val KEY_ENABLE_SEARCH_GROUNDING = "enable_search_grounding"
34+
const val KEY_ENABLE_BOOKING_ASSISTANT = "enable_booking_assistant"
3435

3536
private var appContext: Context? = null
3637

@@ -87,6 +88,10 @@ object FeatureFlags {
8788

8889
val ENABLE_SEARCH_GROUNDING: Boolean
8990
get() = readFlag(KEY_ENABLE_SEARCH_GROUNDING, true)
91+
92+
val ENABLE_BOOKING_ASSISTANT: Boolean
93+
get() = readFlag(KEY_ENABLE_BOOKING_ASSISTANT, true)
94+
9095
private fun readLongFlag(keyName: String, defaultValue: Long): Long {
9196
val context = appContext ?: return defaultValue
9297
return context
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2026 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
plugins {
18+
alias(libs.plugins.android.library)
19+
alias(libs.plugins.kotlin.compose)
20+
alias(libs.plugins.hilt.android)
21+
alias(libs.plugins.google.devtools.ksp)
22+
}
23+
24+
android {
25+
namespace = "com.example.jetpacker.feature.booking_assistant"
26+
compileSdk = libs.versions.compileSdk.get().toInt()
27+
defaultConfig { minSdk = libs.versions.minSdk.get().toInt() }
28+
compileOptions {
29+
sourceCompatibility = JavaVersion.VERSION_17
30+
targetCompatibility = JavaVersion.VERSION_17
31+
}
32+
buildFeatures { compose = true }
33+
}
34+
35+
dependencies {
36+
implementation(libs.androidx.core.ktx)
37+
implementation(project(":core:ui"))
38+
implementation(project(":core:flags"))
39+
implementation(project(":data:itinerary"))
40+
implementation(project(":data:trips"))
41+
42+
implementation(platform(libs.androidx.compose.bom))
43+
implementation(libs.androidx.compose.material3)
44+
implementation(libs.androidx.compose.material.icons.core)
45+
implementation(libs.androidx.compose.material.icons.extended)
46+
implementation(libs.androidx.compose.ui.tooling.preview)
47+
debugImplementation(libs.androidx.compose.ui.tooling)
48+
implementation(libs.androidx.compose.ui)
49+
implementation(libs.androidx.lifecycle.viewmodel.compose)
50+
implementation(libs.androidx.lifecycle.runtime.compose)
51+
implementation(libs.androidx.hilt.navigation.compose)
52+
implementation(libs.hilt.android)
53+
"ksp"(libs.hilt.compiler)
54+
55+
// A2UI Compose Renderer (Jetpack snapshot build 16368166)
56+
implementation(libs.androidx.a2ui.model)
57+
implementation(libs.androidx.a2ui.compose.runtime)
58+
implementation(libs.androidx.a2ui.compose.ui)
59+
implementation(libs.androidx.compose.material3.a2ui)
60+
61+
// Cloud Run backend streaming
62+
implementation(libs.okhttp)
63+
implementation(platform(libs.firebase.bom))
64+
implementation(libs.firebase.auth.ktx)
65+
implementation(libs.kotlinx.coroutines.play.services)
66+
}
67+
68+
kotlin { jvmToolchain(17) }
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
Copyright 2026 The Android Open Source Project
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
18+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
19+
package="com.example.jetpacker.feature.booking_assistant" />

0 commit comments

Comments
 (0)