Skip to content

chore: upgrade Android examples to LeapSDK 0.9.7 with new model downloader#36

Merged
iamstuffed merged 5 commits intomainfrom
dberrios/updateExamples
Feb 5, 2026
Merged

chore: upgrade Android examples to LeapSDK 0.9.7 with new model downloader#36
iamstuffed merged 5 commits intomainfrom
dberrios/updateExamples

Conversation

@iamstuffed
Copy link
Contributor

@iamstuffed iamstuffed commented Jan 29, 2026

Upgrade Android Examples to LeapSDK 0.9.7

This PR upgrades all Android examples to LeapSDK 0.9.7 and adopts the Android-specific LeapModelDownloader API for enhanced download management with platform-native features.

📦 Updated Examples

All 5 Android examples upgraded:

  • SloganApp - Slogan generation demo
  • LeapChat - Full-featured chat with tool calling
  • RecipeGenerator - Constrained JSON output demo
  • ShareAI - Web summary generator
  • VLMExample - Vision language model demo

🆕 New Features

1. LeapModelDownloader - Android-Specific API

Migrated from KMP LeapDownloader to Android-specific LeapModelDownloader:

  • LeapDownloader is the Kotlin Multiplatform (KMP) API - works on all platforms
  • LeapModelDownloader is Android-specific and provides a superset of functionality
  • Uses LeapDownloader internally while adding Android-native features:
    • 🔔 System notifications
    • 📊 WorkManager-based downloads
    • 📱 Android lifecycle awareness
    • ⚙️ Platform-optimized download management

Before (KMP API):

val downloader = LeapDownloader(
    config = LeapDownloaderConfig(saveDir = "$filesDir/leap_models")
)
modelRunner = downloader.loadModel(
    modelName = "Model-Name",
    quantizationSlug = "Q8_0"
)

After (Android API):

val downloader = LeapModelDownloader(
    context,
    notificationConfig = LeapModelDownloaderNotificationConfig.build {
        notificationTitleDownloading = "Downloading Model"
        notificationTitleDownloaded = "Model Ready!"
    }
)
modelRunner = downloader.loadModel(
    modelName = "Model-Name",
    quantizationType = "Q8_0"
)

2. Download Progress Tracking 📊

Real-time download progress with Flow-based status updates:

val currentStatus = downloader.queryStatus(modelName, quantType)

if (currentStatus is ModelDownloadStatus.NotOnLocal) {
    val progressFlow = downloader.observeDownloadProgress(modelName, quantType)
    downloader.requestDownloadModel(modelName, quantType)

    progressFlow
        .onEach { progress ->
            // Display: "Downloading: 45% (120 MB / 500 MB)"
        }
        .takeWhile { progress ->
            progress != null || downloader.queryStatus(modelName, quantType) is DownloadInProgress
        }
        .collect()
}

3. Android System Notifications 🔔

Platform-native notifications during model downloads with custom per-app titles:

  • SloganApp: "Downloading Slogan Generator Model"
  • LeapChat: "Downloading Chat Model"
  • RecipeGenerator: "Downloading Recipe Generator Model"
  • ShareAI: "Downloading ShareAI Model"
  • VLMExample: "Downloading VLM Model"

4. Singleton Pattern 🔒

Prevents concurrent download issues by reusing downloader instance:

private var downloader: LeapModelDownloader? = null

// Reuse instance across calls
if (downloader == null) {
    downloader = LeapModelDownloader(context, notificationConfig)
}

5. Cleaner Flow Control 🎨

Separated concerns for better readability:

progressFlow
    .onEach { progress -> /* display logic */ }
    .takeWhile { progress -> /* control logic */ }
    .collect()

🔄 API Changes

Updated Dependencies

// Added to all examples
implementation(libs.leap.sdk)              // Updated to 0.9.7
implementation(libs.leap.model.downloader) // New Android-specific module

Parameter Renames

More semantic and consistent:

  • quantizationSlugquantizationType

Permissions Added

<!-- For Android 13+ notification support -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

📊 Statistics

  • Files changed: 31
  • Lines added: 578
  • Lines removed: 183
  • Net change: +395 lines
  • Commits: 3 (squashed from original development)

✨ Benefits

  1. Better UX: Users see real-time download progress and system notifications
  2. Platform-Native: Leverages Android's WorkManager and notification system
  3. Robustness: Singleton pattern prevents concurrent download conflicts
  4. Maintainability: Cleaner code with separated concerns
  5. Feature-Rich: Access to Android-specific features while maintaining KMP compatibility
  6. Consistency: All examples follow the same pattern

💡 Why LeapModelDownloader?

While LeapDownloader (KMP) works perfectly on Android, LeapModelDownloader provides:

  • Android notifications - Keep users informed via notification tray
  • WorkManager integration - Reliable downloads even if app is backgrounded
  • Better progress tracking - Platform-optimized download monitoring
  • Lifecycle awareness - Proper handling of Android app lifecycle
  • All KMP features - Uses LeapDownloader internally as the foundation

Both APIs remain available - use LeapDownloader for KMP projects, LeapModelDownloader for Android-specific apps that want enhanced features.

📝 Documentation

  • Added LeapKoogAgent to main README (was missing from examples list)
  • Fixed LeapChat README to reflect Kotlin Serialization usage (not Gson)
  • Enhanced RecipeGenerator README with download details

🔄 Dependency Updates

All Android examples updated to latest stable versions:

  • Kotlin: 2.3.0 → 2.3.10
  • Compose BOM: 2025.12.01 → 2026.01.01
  • activity-compose: 1.12.2 → 1.12.3
  • kotlinx-serialization-json: 1.8.0 → 1.10.0
  • jsoup: 1.16.1 → 1.22.1 (ShareAI)
  • kaml: 0.85.0 → 0.104.0 (VLMExample)

Kept AGP at 8.13.2 (skipped 9.0.0 major version to avoid breaking changes).

🧪 Testing

All examples tested with:

  • ✅ First-time model downloads
  • ✅ Progress tracking and notifications
  • ✅ Model loading after download
  • ✅ Concurrent download prevention
  • ✅ Clean flow control logic
  • ✅ Background download handling

🔗 Related

  • Upgrades from LeapSDK 0.9.6 to 0.9.7
  • Uses new leap-model-downloader artifact from Maven Central
  • Compatible with Android API 31+
  • Maintains backward compatibility with KMP LeapDownloader for multiplatform projects

@iamstuffed iamstuffed changed the title chore: upgrade all examples to LeapSDK 0.9.4 with LeapDownloader chore: upgrade all examples to LeapSDK 0.9.6 with LeapDownloader Jan 30, 2026
@iamstuffed iamstuffed force-pushed the dberrios/updateExamples branch from d67e5b5 to caba0b2 Compare January 30, 2026 20:59
@iamstuffed iamstuffed changed the title chore: upgrade all examples to LeapSDK 0.9.6 with LeapDownloader chore: upgrade all Android demos to LeapSDK 0.9.6 Jan 30, 2026
@iamstuffed iamstuffed force-pushed the dberrios/updateExamples branch from caba0b2 to f4039ce Compare January 30, 2026 21:04
@iamstuffed iamstuffed force-pushed the dberrios/updateExamples branch from f4039ce to 9f942f0 Compare February 5, 2026 20:28
@iamstuffed iamstuffed changed the title chore: upgrade all Android demos to LeapSDK 0.9.6 chore: upgrade Android examples to LeapSDK 0.9.7 with new model downloader Feb 5, 2026
…oader

- Upgrade all Android examples from LeapSDK 0.9.6 to 0.9.7
- Migrate from deprecated LeapDownloader to new LeapModelDownloader API
- Add leap-model-downloader dependency to all examples
- Implement download progress tracking with real-time status updates
- Add Android notification support during model downloads
- Use singleton pattern for LeapModelDownloader to prevent concurrent download issues
- Separate progress display logic (onEach) from flow control (takeWhile)
- Update parameter names: modelSlug -> modelName, quantizationSlug -> quantizationType
- Add POST_NOTIFICATIONS permission for Android 13+
- Update RecipeGenerator with enhanced download progress monitoring
@iamstuffed iamstuffed force-pushed the dberrios/updateExamples branch from 9f942f0 to 4e0514c Compare February 5, 2026 20:33
Updated dependencies across all Android examples:
- Kotlin: 2.3.0 → 2.3.10
- Compose BOM: 2025.12.01 → 2026.01.01
- activity-compose: 1.12.2 → 1.12.3
- kotlinx-serialization-json: 1.8.0 → 1.10.0
- jsoup: 1.16.1 → 1.22.1
- kaml: 0.85.0 → 0.104.0

Kept AGP at 8.13.2 (skipped 9.0.0 major version upgrade).
@iamstuffed iamstuffed merged commit 1adf500 into main Feb 5, 2026
1 check passed
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