Package-level declarations

Types

Link copied to clipboard

Preferred compute unit for on-device inference. A hint, not a guarantee: a backend maps it to the nearest unit its engine offers and degrades silently — MediaPipe (tasks-genai) has no NPU backend so NPU falls back to the engine default, and Gemini Nano always runs on the NPU/AICore regardless.

Link copied to clipboard

Detection-ordered OnDeviceLlm (ai-engineering.md §7): probes an ordered list of backends and uses the first one that both reports available AND actually produces output. This is how a device escalates ML Kit Gemini Nano (AICore-only) → MediaPipe Gemma (broad device coverage, downloaded on demand) → (nothing → the heuristic tier takes over upstream in DefaultJobIntelligence).

Link copied to clipboard
data class DownloadProgress(val receivedBytes: Long, val totalBytes: Long, val bytesPerSec: Long, val etaMs: Long)

Live progress of a model download. receivedBytes/totalBytes drive a progress bar; bytesPerSec and etaMs drive a "12 MB/s · 2 min left" label. totalBytes and etaMs are -1 when unknown (server sent no Content-Length).

Link copied to clipboard
data class GenerationConfig(val topK: Int? = null, val topP: Float? = null, val temperature: Float? = null, val maxTokens: Int? = null, val accelerator: Accelerator? = null)

Optional load-time tuning for an on-device LLM. Every field is nullable — null means "leave the backend's own default alone". Backends apply what their engine exposes and ignore the rest:

Link copied to clipboard
sealed interface LlmPart

One piece of multimodal input to OnDeviceLlm.generate. ByteArray (not a platform bitmap type) keeps this commonMain-safe — each platform actual decodes the bytes itself.

Link copied to clipboard
class MediaPipeModelManager(context: Context, spec: ModelManifestEntry = GEMMA_3_1B, downloader: ResumableModelDownloader = ResumableModelDownloader()) : ModelManager

Manages the on-demand MediaPipe Gemma model file in app-private storage. The model binary is NEVER committed to the repo — download is user-triggered (surfaced on the settings screen via ModelManager) and lands in filesDir/models/, resuming from a .tmp if a prior attempt was cut off.

Link copied to clipboard
class MediaPipeOnDeviceLlm(context: Context, modelManager: MediaPipeModelManager, config: GenerationConfig? = null) : OnDeviceLlm
Link copied to clipboard
Link copied to clipboard

Lifecycle of a downloadable on-device model (e.g. MediaPipe Gemma). PARTIALLY_DOWNLOADED marks a .tmp left behind by an interrupted download — the next ModelManager.download resumes from it.

Link copied to clipboard
data class ModelInfo(val id: String, val displayName: String, val approxSizeMb: Int, val state: ModelDownloadState, val progress: Float = 0.0f, val downloadProgress: DownloadProgress? = null, val error: String? = null)

A downloadable on-device model, surfaced to the settings screen.

Link copied to clipboard
interface ModelManager

The settings-screen-facing control surface for optional downloadable on-device models. Kept tiny on purpose (list / observe / download / delete). Backends that need no download (ML Kit Gemini Nano is managed by AICore; Foundation Models by the OS) don't appear here — only models the app fetches itself (MediaPipe Gemma) do.

Link copied to clipboard
data class ModelManifestEntry(val id: String, val displayName: String, val approxSizeMb: Int, val fileName: String, val hfRepo: String, val hfFile: String, val requiresLicenseAck: Boolean = false)

Config-driven description of a downloadable on-device model — the manifest a ModelManager reads instead of hard-coding one model. Keeps model choice out of code: an app ships (or fetches) a list of these and the manager downloads/manages each by id.

Link copied to clipboard

Default for platforms/targets with no downloadable models (JVM/desktop, iOS today).

Link copied to clipboard
interface OnDeviceLlm

A single-shot on-device text LLM tier. Kept deliberately tiny — one availability gate and one text-in/text-out call — so each platform's actual (ML Kit GenAI on Android, Foundation Models on iOS, unavailable elsewhere) is a thin wrapper, and DefaultJobIntelligence never has to know which backend ran.

Link copied to clipboard
class ResumableModelDownloader(bearerToken: String? = null, bufferSize: Int = 64 * 1024, connectTimeoutMs: Int, readTimeoutMs: Int, nanoTime: () -> Long = System::nanoTime)
Link copied to clipboard

The common fallback tier: no on-device model. Desktop/JVM/wasm and any pre-AI device land here.

Properties

Link copied to clipboard

True when any sampler field is set — i.e. the backend must override its default decoding.

Functions

Link copied to clipboard
fun computeDownloadProgress(received: Long, total: Long, elapsedMs: Long, startOffset: Long = 0): DownloadProgress

Pure progress/speed/ETA calc for a resumable download — no I/O, so it is unit-testable. received is the total bytes on disk (including any resumed startOffset); elapsedMs is time since THIS session started, so speed reflects the live transfer, not the resumed head start.

Link copied to clipboard
actual fun onDeviceLlmModule(): Module

Android on-device LLM tier, detection-ordered (ai-engineering.md §7): ML Kit Gemini Nano (AICore devices) → MediaPipe Gemma (broad coverage, downloaded on demand) → (falls through to the heuristic tier upstream). ModelManager is bound for the settings screen.

expect fun onDeviceLlmModule(): Module

Per-platform Koin bindings for the on-device LLM tier. commonMain's aiModule includes this; the actual decides which OnDeviceLlm gets bound (ML Kit / Foundation Models / unavailable).

actual fun onDeviceLlmModule(): Module

iOS on-device LLM tier, detection-ordered (ai-engineering.md §7): Apple Foundation Models → MediaPipe Gemma → (falls through to the heuristic tier upstream).

actual fun onDeviceLlmModule(): Module

Desktop/JVM has no on-device model — the heuristic tier always answers.