Skip to main content

Error Handling

All errors are thrown as LeapException, which has following subclasses:
  • LeapModelLoadingException : error in loading the model
  • LeapGenerationException : error in generating content
  • LeapGenerationPromptExceedContextLengthException: the prompt text exceeds the maximum context length so no content will be generated
  • LeapSerializationException : error in serializing / deserializing data.

Serialization Support

The LEAP SDK uses kotlinx.serialization for JSON serialization and deserialization. This is built into the core SDK and requires no additional dependencies. The following types are @Serializable:

Serializing and Deserializing Conversation History

Add kotlinx.serialization to your project:
// app/build.gradle.kts
plugins {
    id("org.jetbrains.kotlin.plugin.serialization") version "2.3.10"
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
}
Save conversation history:
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString

val json = Json { ignoreUnknownKeys = true }

// Serialize to JSON string
val jsonString = json.encodeToString(conversation.history)

// Save to SharedPreferences, file, database, etc.
sharedPreferences.edit().putString("conversation_history", jsonString).apply()
Restore conversation history:
import kotlinx.serialization.decodeFromString

// Load from storage
val jsonString = sharedPreferences.getString("conversation_history", null)

if (jsonString != null) {
    val history = json.decodeFromString<List<ChatMessage>>(jsonString)
    val restoredConversation = modelRunner.createConversationFromHistory(history)
}
Serialize single message:
val message = ChatMessage(
    role = ChatMessage.Role.USER,
    content = listOf(ChatMessageContent.Text("Hello"))
)

val messageJson = json.encodeToString(message)

LeapModelDownloader (Android)

LeapModelDownloader is the recommended option for Android applications. It provides background downloads with WorkManager, foreground service notifications, and robust handling of network interruptions.
The LeapSDK Android Model Downloader module is a production-ready helper for downloading models from the LEAP Model Library on Android. It runs as a foreground service and displays notifications to users during downloads.

Permission Setup

The model downloader requires notification permissions to display download progress. You need to:
  1. Add permissions to AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
  1. Request notification permission at runtime (Android 13+):
// In your Activity
private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
    if (isGranted) {
        Log.d(TAG, "Notification permission granted")
        // Proceed with download
    } else {
        Log.w(TAG, "Notification permission denied")
        // Handle permission denial
    }
}

// Before downloading
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    if (ContextCompat.checkSelfPermission(
            this,
            android.Manifest.permission.POST_NOTIFICATIONS
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
    }
}

Installation

// In build.gradle.kts
dependencies {
  implementation("ai.liquid.leap:leap-sdk:0.9.7")
  implementation("ai.liquid.leap:leap-model-downloader:0.9.7")
}

Basic Usage

import ai.liquid.leap.model_downloader.LeapModelDownloader
import ai.liquid.leap.model_downloader.LeapModelDownloaderNotificationConfig

// Initialize (in onCreate or similar)
val modelDownloader = LeapModelDownloader(
    context,
    notificationConfig = LeapModelDownloaderNotificationConfig.build {
        notificationTitleDownloading = "Downloading AI model..."
        notificationTitleDownloaded = "Model ready!"
        notificationContentDownloading = "Please wait..."
    }
)

// Download and load model
lifecycleScope.launch {
    try {
        val modelRunner = modelDownloader.loadModel(
            modelSlug = "LFM2-1.2B",
            quantizationSlug = "Q5_K_M",
            progress = { progressData ->
                Log.d(TAG, "Progress: ${progressData.progress * 100}%")
            }
        )
        // Model is ready to use
    } catch (e: Exception) {
        Log.e(TAG, "Failed to load model: ${e.message}")
    }
}

API Reference

LeapModelDownloader

LeapModelDownloader is the instance to make request of downloading models and to query the status of a model download request.
class LeapModelDownloader(
    private val context: Context,
    modelFileDir: File? = null,
    private val extraHTTPRequestHeaders: Map<String, String> = mapOf(),
    private val notificationConfig: LeapModelDownloaderNotificationConfig = LeapModelDownloaderNotificationConfig(),
) {
  fun getModelFile(model: DownloadableModel): File
  fun requestDownloadModel(model: DownloadableModel, forceDownload: Boolean = false)
  fun requestStopDownload(model: DownloadableModel)
  suspend fun queryStatus(model: DownloadableModel): ModelDownloadStatus
  fun requestStopService()
}

Constructor parameters

  • context: The Android context to retrieve cache directory and launch services. The activity context works for this purpose.
  • modelFileDir: The path to store model files. If it is not set, a path in the app’s external file dir will be used.
  • extraHTTPRequestHeaders: Any extra HTTP request headers to send when downloading a model.
  • notificationConfig: Configuration on the content of Android notifications visible to the users.

getModelFile

Return a file object of the model file based on the DownloadableModel instance. The file may not exists.

requestDownloadModel

Make a request to download the model. If the model file already exists locally, it won’t be downloaded.
  • model: A DownloadableModel instance.
  • forceDownload: If it’s true, downloader will remove the model bundle file that exists locally and to conduct the download.

requestStopDownload

Make a request to stop downloading a model.

queryStatus

Query the status of the model. The return value is a ModelDownloadStatus object:
sealed interface ModelDownloadStatus {
  data object NotOnLocal: ModelDownloadStatus
  data class DownloadInProgress(
    val totalSizeInBytes: Long,
    val downloadedSizeInBytes: Long,
  ): ModelDownloadStatus
  data class Downloaded(
    val totalSizeInBytes: Long,
  ) : ModelDownloadStatus
}
There are three possible value types:
  • NotOnLocal The model file has not been downloaded or has already been deleted.
  • DownloadInProgress The model file is still being downloaded. totalSizeInBytes is the total size of the file and downloadedSizeInBytes is the size of downloaded portion. If the total size is not available, totalSizeInBytes will be -1.
  • Downloaded The file has been downloaded. totalSizeInBytes is the file size.

requestStopService

Make a request to stop the foreground service of the model downloader.

DownloadableModel

DownloadableModel is an interface to describe the model can be downloaded by the LeapSDK Model Downloader.
interface DownloadableModel {
  val uri: Uri
  val name: String
  val localFilename: String
}
  • uri: The URI of the model to download.
  • name: A user-friendly name of the model. It will be displayed in the notification.
  • localFilename: The filename to store the model bundle file locally.

LeapDownloadableModel

LeapDownloadableModel implements DownloadableModel. It is designed to download models from Leap Model Library. resolve method is provided to retrieve the model from Leap Model Library.
class LeapDownloadableModel {
  companion object {
    suspend fun resolve(modelSlug: String, quantizationSlug: String) : LeapDownloadableModel?
  }
}
The resolve method accepts 2 parameters:
  • modelSlug: The model slug that identifies the model. It is usually the lowercase string of the model name. For example, the slug of LFM2-1.2B is lfm2-1.2b.
  • quantizationSlug: The model quantization slug. It can be found in the “Available quantizations” section of the model card.