leap-ui module (introduced in v0.10.0) ships a ready-to-use voice assistant widget โ an animated orb, mic button, and status label โ backed by a state machine that handles recording, generation, and audio playback. Wire it to a model and it handles the rest.
leap-ui is a Compose Multiplatform module, so the same widget runs on:
- iOS โ bridged to UIKit via
VoiceAssistantViewControllerand exposed to SwiftUI throughUIViewControllerRepresentable. - macOS โ bridged to AppKit via
VoiceAssistantNSViewController. SwiftUI hosts viaNSViewControllerRepresentable+NSHostingController. - Android โ direct Compose for Android.
- JVM Desktop โ Compose for Desktop. Same Maven artifact; you provide audio I/O implementations (the demo apps in
leap-ui-demo/ship patterns you can adapt). - Web (Wasm, experimental) โ present in the source tree (
leap-ui-demo/web) but not yet covered by the stable release notes through v0.10.7 โ treat as preview.
Add the dependency
- iOS / macOS (SPM)
- Android / JVM (Gradle)
Add the In Swift sources,
LeapUI product to your target alongside LeapModelDownloader (the SPM product whose Swift ModelDownloader class is what the snippets below use to load the audio model). See the Quick Start for the full SPM setup.import LeapUi (lowercase i โ thatโs the binary-target module name).Architecture
VoiceAssistantStoreowns the session lifecycle. Instantiate once when the screen appears;close()it when it goes away.VoiceConversationis a thin interface you implement to bridge the store to your model. Wrap the SDKโsConversation.generateResponseand forwardAudioSamplechunks toonAudioChunk.- Audio I/O uses
VoiceAudioRecorder/VoiceAudioPlayerinterfaces. iOS / macOS shipAppleAudioRecorderandAppleAudioPlayerdefaults; Android / JVM reference implementations live inleap-ui-demo/.
Wire the model
TheVoiceConversation adapter looks similar on every platform โ both implementations stream audio samples back through onAudioChunk.
- Swift (iOS / macOS)
- Kotlin (Android)
The factory Override defaults via the same
VoiceAssistantStore.makeForApple() hides Kotlin coroutine plumbing from Swift callers. It creates the store with a MainScope(), the default Apple audio recorder and player, and an EMA-smoothed amplitude.makeForApple factory parameters:Host the widget
- Swift (iOS)
- Swift (macOS)
- Kotlin (Android / Compose Desktop)
Implement VoiceConversation
The store calls into a VoiceConversation you provide. A minimal adapter that wraps a normal Conversation:
- Swift (iOS / macOS)
- Kotlin (all platforms)
The
VoiceConversation protocol comes from LeapUI, so its audioSamples and onAudioChunk parameters use LeapUi.KotlinFloatArray / LeapUi.KotlinInt โ not native Swift [Float] / Int32. The on-device runner lives in LeapSDK, which has its own LeapSDK.KotlinFloatArray. Bridge between the two via the floatArrayToNSData / nsDataToFloatArray helpers exposed in both frameworks (see leap-ui-demo/shared/AppleVoiceConversation.swift for the canonical pattern).Audio I/O implementations
TheVoiceAudioRecorder and VoiceAudioPlayer contracts are short. Substitute your own implementations when the defaults donโt fit.
- iOS / macOS
- Android
- JVM Desktop
AppleAudioRecorder and AppleAudioPlayer are the shipped defaults โ makeForApple() wires them up automatically. Implement the protocols directly if you need to integrate with custom AVAudioEngine pipelines.iOS apps must configure AVAudioSession for record + playback before the model starts streaming audio:NSMicrophoneUsageDescription to your Info.plist.interruptToSpeak
VoiceAssistantStore (v0.10.0+) exposes an interruptToSpeak: Boolean = true parameter controlling what happens when the user presses the orb during a response:
true(default) โ cancels the in-flight generation and immediately starts a new recording.falseโ only cancels. The user must press again to start a new recording.
- Swift (iOS / macOS)
- Kotlin (all platforms)
Whatโs in the module
| Symbol | Purpose |
|---|---|
VoiceAssistantStore | State machine + orchestrator. Apple platforms: makeForApple(). |
VoiceAssistantStateHolder | Compose-friendly state container, exposed to Swift. |
VoiceAssistantWidget (Compose) | The widget itself. Drop into any Compose tree (Android, JVM, iOS via host controller, macOS via host controller). |
VoiceAssistantViewController (UIKit) / VoiceAssistantNSViewController (AppKit) | Pre-built hosts for Apple. |
AppleAudioRecorder / AppleAudioPlayer | Default audio I/O on iOS / macOS. |
VoiceConversation | Adapter interface you implement to bridge the store to a Conversation. |
VoiceWidgetLabels, VoiceWidgetColors | Theming (use .companion.Default to access the canonical palette). |
Compatible models
Voice mode requires a model that emits audio output. The shipped demo usesLFM2.5-Audio-1.5B at Q4_0 quantization, with a system prompt of โRespond with interleaved text and audio.โ See the LEAP Model Library for other audio-capable models.