Skip to content

Latest commit

 

History

History

jetpacker

README.md

JetPacker

Home Screen Trip Itinerary Flight Detail
Home Screen Trip Itinerary Flight Detail Screen

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, coordinate reservations with an AI Booking Assistant using Jetpack A2UI, and contribute to Android's intelligence system with trip management functions through 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
  • On-Device AI: ML Kit GenAI (Prompt, Speech Recognition, Translation)
  • Cloud & Hybrid AI: Firebase AI Logic (Gemini grounded with URL/Maps/Search, and hybrid models with on-device fallback)
  • App Security: Firebase App Check (with Play Integrity and Debug Provider)
  • Assistant Integration: Android AppFunctions (androidx.appfunctions)

Module Overview

JetPacker follows a clean, multi-module Android structure organized by responsibility and domain:

Core Modules (:core:*)

  • :core:ui: Shared Jetpack Compose design system components (JetPackerFab, JetPackerToolbar, themes, custom typography).
  • :core:flags: Centralized feature toggle system (FeatureFlags) controlling optional runtime capabilities.
  • :core:speech: On-device speech recognition wrappers and audio processing utilities.

Data Modules (:data:*)

  • :data:db: Room database configuration, entities, and local DAOs.
  • :data:trips: Repository layer and data models managing high-level trip records.
  • :data:itinerary: Repository layer and data models managing daily itinerary events (TimelineEvent, EventType).

Feature Modules (:feature:*)

  • :feature:home: Dashboard screen displaying the user's upcoming trips list.
  • :feature:create_trip: Unified trip form module handling both new trip creation and existing trip editing (EditTripScreen).
  • :feature:detail: Detailed view screens for specific itinerary events (Flights, Hotels, Restaurants, Museums, Tours).
  • :feature:appfunctions: Android AppFunctions framework integration (JetPackerAppFunctionService) contributing structured functions to Android's intelligence system for trips, expenses, itineraries, and voice notes.
  • :feature:trip: Top-level trip container shell (TripScreen) holding bottom navigation and orchestrating trip sub-tabs.
    • :feature:trip:itinerary: Pure itinerary timeline screen displaying daily scheduled events.
      • :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

This project is built using the standard Android Gradle build system, allowing developers to quickly build, run, and experiment with the application locally using Android Studio.

Configuration Setup

  1. Local Properties Setup:

    • Navigate to the android directory and copy local.properties.example to local.properties:
      cd android
      cp local.properties.example local.properties
    • Update sdk.dir inside local.properties with your local Android SDK directory path.
  2. Firebase Setup (google-services.json):

    • Register an Android app in your Firebase Project Console using the package name com.example.jetpacker.
    • In the Firebase Console, navigate to Authentication -> Sign-in method and enable Anonymous sign-in (used for session-based communication with the booking coordinator and AI services).
    • Download your project's google-services.json and place it in the android/app/ directory (replacing the mock placeholder file). The Gradle google-services plugin automatically parses this file and configures the required resources at build time—no code changes or extra XML files are required.
    • Git Safety: To prevent accidentally committing your personal Firebase credentials back to the repository, tell git to ignore local changes to this file:
      git update-index --skip-worktree android/app/google-services.json
  3. Firebase App Check Debug Attestation:

    • Run the application on an emulator or a connected device.
    • Filter your logcat logs for DebugAppCheckProvider. You will see a log similar to:
      Enter this debug secret into the allow list in the Firebase Console for your project: a8c2dd4c-7f7f-4764-b653-ef6c114ba27e
      
    • Copy the debug token and register it in the Firebase Console under App Check -> Apps -> Manage Debug Tokens.

Building Using Gradle

To compile the application and run unit tests using Gradle, execute the following commands in your terminal (from the android directory):

# Navigate to the android directory
cd android

# Build a debug APK
./gradlew :app:assembleDebug

# Run unit tests
./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:

# 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:

docker build -t jetpacker-server .
docker run -p 8080:8080 jetpacker-server

Deploying to Google Cloud Run (Production vs Parallel Staging)

The booking server can be deployed to Cloud Run behind a Google Cloud API Gateway that validates Firebase Authentication tokens.

We support side-by-side execution so you can run and test updates on a parallel staging backend without affecting the production service:

  • Production Service (jetpacker-server): Backs / routes on API Gateway (/stream, /respond, etc.).
  • Parallel Staging Service (jetpacker-server-v2): Backs /v2/* routes on API Gateway (/v2/stream, /v2/respond, etc.).
Deploying to Parallel Staging (jetpacker-server-v2)
  1. Build and submit the image:
    gcloud builds submit --tag gcr.io/android-devrel-ci/jetpacker-server:v2 \
        --project=android-devrel-ci server/
  2. Deploy to Cloud Run:
    gcloud run deploy jetpacker-server-v2 \
        --image gcr.io/android-devrel-ci/jetpacker-server:v2 \
        --region us-central1 \
        --project android-devrel-ci \
        --set-env-vars CLOUD_RUN_AUDIENCE=https://jetpacker-server-v2-254502043090.us-central1.run.app \
        --no-allow-unauthenticated
Deploying to Production (jetpacker-server)
  1. Build and submit the image:
    gcloud builds submit --tag gcr.io/android-devrel-ci/jetpacker-server:latest \
        --project=android-devrel-ci server/
  2. Deploy to Cloud Run:
    gcloud run deploy jetpacker-server \
        --image gcr.io/android-devrel-ci/jetpacker-server:latest \
        --region us-central1 \
        --project android-devrel-ci \
        --set-env-vars CLOUD_RUN_AUDIENCE=https://jetpacker-server-254502043090.us-central1.run.app \
        --no-allow-unauthenticated
Updating the API Gateway Config

To update API Gateway routes using server/openapi.yaml:

gcloud api-gateway api-configs create jetset-config-v<N> \
    --api=jetset-api \
    --openapi-spec=server/openapi.yaml \
    --project=android-devrel-ci \
    --backend-auth-service-account=api-gateway-invoker@android-devrel-ci.iam.gserviceaccount.com

gcloud api-gateway gateways update jetset-gateway \
    --api=jetset-api \
    --api-config=jetset-config-v<N> \
    --location=us-central1 \
    --project=android-devrel-ci
Configuring the Android App Endpoint

In BookingAssistantViewModel.kt, adjust backendEndpoint:

  • BackendEndpoint.PARALLEL_STAGING (default): Connects to /v2 on API Gateway (jetpacker-server-v2).
  • BackendEndpoint.PRODUCTION: Connects to / on API Gateway (jetpacker-server).
  • BackendEndpoint.LOCAL: Connects to http://localhost:8000 (via adb reverse tcp:8000 tcp:8000).

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.
  • ENABLE_ITINERARY_ENRICHMENT: Local enrichment for timeline events.
  • ENABLE_EXPENSE_MANAGEMENT: Local expense management receipt scanner and parser.
  • ENABLE_VOICE_NOTES: On-device speech recognition and transcription for voice notes.

Cloud-Hybrid & Online AI Features

JetPacker also integrates online hybrid features using Firebase AI Logic (Gemini API) and ML Kit:

  • 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 library (androidx.appfunctions) in :feature:appfunctions to contribute to Android's intelligence system with structured travel actions and data queries via JetPackerAppFunctionService:

  • Trip Management: searchTrip (filter by ID, name, location, and dates) and createTrip.
  • Itinerary Events: getItinerary and addItineraryEvent (activity, dining, accommodation, etc.).
  • Expense Tracking: getExpenses and addExpense (amount, currency, category).
  • Voice Notes: getVoiceNotes and addVoiceNote (recorded transcriptions linked to trips).
  • Day Themes: getDayThemes and setDayTheme for daily trip customization.

IDE Setup & Development

To work on JetPacker locally, open the project in Android Studio:

  1. Open Android Studio and select Open an Existing Project (or File > Open).
  2. Select the android directory folder within the repository.
  3. Android Studio will automatically sync Gradle and prepare the project.