FOR DEVELOPERS

Integrate EdgeLM in a few lines.

Your app calls the shared EdgeLM runtime — a separate app the user installs once from Google Play. You never ship or manage model weights, and the model stays resident in memory shared across every EdgeLM-powered app.

minSdk 26 · tiny client SDK (Binder + coroutines) · no manifest changes needed

1 · ADD THE DEPENDENCY

Pull the SDK from JitPack.

In settings.gradle.kts (or your root build.gradle), add the JitPack repo:

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}

Then in your app module's build.gradle.kts:

dependencies {
    implementation("com.github.Chandra-Mauli-Sharma.EdgeLM:sdk:0.1.0")
}

The :contract module (AIDL/Binder types) comes in transitively. No manifest changes needed — the SDK declares the ai.edgelm.permission.USE_RUNTIME permission and the package <queries> for you via manifest merge.

2 · MAKE SURE THE RUNTIME IS INSTALLED

Check up front, prompt if missing.

EdgeLM is a shared runtime, so the EdgeLM Runtime app must be installed — the user gets it once from Play, and every EdgeLM app then shares it.

when (EdgeLM.status(context)) {
    EdgeLM.Status.NOT_INSTALLED -> EdgeLM.promptInstall(context)  // sends user to Play
    EdgeLM.Status.AVAILABLE     -> EdgeLM.initialize(context)     // bind the service
}
NOT_INSTALLED

promptInstall(context)

Opens the runtime's Play page (market:// with a web fallback) so the user can install it.

AVAILABLE

initialize(context)

Binds to the runtime service. Idempotent — safe to call more than once, e.g. from Application.onCreate.

3 · STREAM A COMPLETION

An OpenAI-style, coroutine-native API.

chat(...) returns a cold Flow<String> of tokens — work starts on collect, and cancelling the collector's scope cancels the on-device decode.

EdgeLM.initialize(context)          // once (e.g. Application.onCreate)

lifecycleScope.launch {
    try {
        EdgeLM.chat(
            model = "default",       // Phase 0 serves the active model; value is advisory
            prompt = "Explain on-device AI in one line",
            sessionId = "chat-1",    // stable id = multi-turn; "" = stateless one-shot
            priority = EdgeLM.INTERACTIVE,
        ).collect { token ->
            appendToUi(token)        // tokens stream in
        }
    } catch (e: EdgeLMUnavailableException) {
        // runtime missing or not responding — fall back / prompt install
    }
}

Multi-turn conversations

Pass a stable sessionId. Prior turns stay in the runtime's warm KV cache and aren't re-prefilled, so follow-ups are fast:

EdgeLM.chat("default", "My name is Ada.", sessionId = "s1").collect { … }
EdgeLM.chat("default", "What's my name?", sessionId = "s1").collect { … }  // remembers

Priority

Requests are admitted to the single shared engine by priority, with aging:

3 · FOREGROUND

User is watching

The user is staring at the result right now.

2 · INTERACTIVE

Default

The standard priority for normal chat traffic.

1 · BATCH

Batch work

Lower urgency, processed as capacity allows.

0 · BACKGROUND

Best-effort

Background work with the lowest scheduling priority.

4 · LIFECYCLE

Three calls, start to finish.

EdgeLM.initialize(context)

Idempotent; binds the runtime service.

EdgeLM.warmModels()

suspend, returns the models currently loaded — useful for diagnostics.

EdgeLM.shutdown()

Unbind when you're done. Optional — the runtime stays alive for other apps regardless.

NOTES

Good to know.

PUBLISHING NOTE · MAINTAINERS

JitPack builds from a git tag. To release a version, tag it to match the SDK version (the module publishes version = "0.1.0"):

git tag 0.1.0 && git push origin 0.1.0

Then the coordinates in Step 1 resolve. Build log: jitpack.io/#Chandra-Mauli-Sharma/EdgeLM

In a hurry?

There's a complete, runnable sample — clone it, ./gradlew installDebug, and you have a working streaming chat app to copy from.