Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.
The LEAP SDK is deprecated and this page is no longer maintained. Build on llama.cpp directly instead — see Migrating from LEAP SDK.
Latest release: v0.10.7 (GitHub).This page covers user-visible changes in the LEAP SDK across releases. For per-build commit detail, see the release notes on Liquid4All/leap-sdk.
0.9.x → 0.10.x: Kotlin Multiplatform unification
Starting with v0.10.0, the LEAP SDK ships from a single Kotlin Multiplatform codebase. The two previously separate distributions (the Android-only ai.liquid.leap:* Maven artifacts and the iOS-only Liquid4All/leap-ios Swift package) were collapsed into one source tree that publishes to:
Swift Package Manager — Liquid4All/leap-sdk (new repo, for iOS / macOS consumers).
Maven Central — ai.liquid.leap:* (Android, JVM, and Kotlin/Native targets).
The standalone Liquid4All/leap-ios repository is no longer the iOS source-of-truth. Existing 0.9.x Swift call sites (Leap.load(...), Conversation.generateResponse(...), etc.) keep compiling thanks to a Swift compatibility layer, but new code should adopt the unified APIs documented in the Quick Start.
Five SPM products / four Maven artifacts
The unified KMP package vends a richer surface than the 0.9.x distributions:
SPM product
Maven artifact
Purpose
LeapSDK
ai.liquid.leap:leap-sdk
Core inference + conversation API
LeapModelDownloader
ai.liquid.leap:leap-model-downloader
Hosted / manifest-based model fetch
LeapOpenAIClient
ai.liquid.leap:leap-openai-client
OpenAI-compatible cloud chat client (new in 0.10.0)
LeapUI
ai.liquid.leap:leap-ui
Voice assistant widget — Compose Multiplatform (new in 0.10.0)
v0.10.0 raises the minimum iOS deployment target from 15.0 to 17.0 and macOS from 12.0 to 15.0. Apps targeting older OSes need to pin to 0.9.x or bump their deployment target before upgrading.
SPM URL change. Point your Swift Package Manager dependency at https://github.com/Liquid4All/leap-sdk.git (not the deprecated leap-ios repo).
CocoaPods removed. The SDK ships exclusively through SPM in v0.10.0 onward.
Toolchain bump. Xcode 16 and Swift 6.0 are required.
Swift downloader name. In current 0.10.x, Swift code instantiates ModelDownloader from the LeapModelDownloader SPM product. Android code still uses the Kotlin class ai.liquid.leap.downloader.LeapModelDownloader. See Model Loading for the constructor signatures.
Major additions since 0.9.x
The features below were introduced in the 0.10.x line.
OpenAI-compatible cloud client
LeapOpenAIClient / leap-openai-client is a small, dependency-light client for any OpenAI-compatible chat completions endpoint — OpenAI itself, OpenRouter, vLLM, llama-server, or your own proxy. It ships in the same package so you can route requests between an on-device LFM and a cloud model from a single app.See OpenAI-Compatible Client.
Voice assistant widget
LeapUI / leap-ui is a Compose Multiplatform module that ships a drop-in voice assistant widget — an animated orb, mic button, and status label — backed by a state machine that handles recording, generation, and audio playback. Stable on iOS, macOS, Android, and JVM; Wasm/Web is present in the source tree as preview.See Voice Assistant Widget.
Sideloading models from explicit paths
LeapDownloader.loadSimpleModel and LeapModelDownloader.loadSimpleModel load a model from explicit resource paths or URLs without going through the LEAP Model Library manifest. Useful for ADB-pushed bundles, app-bundled models, or any setup where you’ve already placed the model files on disk.See Model Loading — Sideloaded files.
iOS background downloads
The iOS / macOS Swift ModelDownloader(sessionConfiguration:) initializer accepts an optional URLSessionConfiguration? so downloads can continue when the app is suspended or killed. See Model Loading → Constructing the downloader.
autoDetectCompanionFiles
Leap.load(url:options:) on iOS gained an autoDetectCompanionFiles: Bool = true parameter that picks up companion files sitting next to the model file (e.g. multimodal projection weights).
Swift ergonomics
Compatibility layer keeps 0.9.x call sites (Leap.load(...), Conversation.generateResponse(...)) compiling on top of the unified KMP surface.
onEnum(of:) — SKIE-bridged sealed-class switching for Kotlin enums and sealed hierarchies (e.g. MessageResponse).
Builder-style options — LiquidInferenceEngineOptions.with(cacheOptions:), etc.
Memory-mapped model loading by default
Starting in v0.10.4 and on by default through the current release, the inference engine loads model weights via mmap (use_mmap=true). It’s the default behavior for every loaded model. On mobile this is the most user-visible runtime change in the 0.10.x line. A public opt-out arrived in v0.10.5 as ModelLoadingOptions.useMmap: Boolean? (Kotlin) / LiquidInferenceEngineOptions(useMmap:) (Swift) — leave it null/nil to keep the default, or set false for filesystems where mmap misbehaves (some Android scoped-storage paths, certain network mounts).What changed. Previously the engine read(2)-ed the entire model file into a heap-allocated buffer before running prefill. Now it memory-maps the file: the kernel maps the on-disk weights into the process’s virtual address space and loads pages lazily as they’re accessed.Performance implications on mobile:
Lower private RSS. mmap’d weights are file-backed pages, not “anonymous private” RSS. iOS’s jetsam and Android’s low-memory killer both score apps primarily by anonymous RSS, so a 1.2B-Q4 model that previously counted as ~700 MB of dirty heap now shows as backing pages the OS may evict for free. Foreground apps are significantly less likely to be terminated under memory pressure.
Faster cold load. The constructor returns as soon as the file is mapped — typically tens of milliseconds — instead of waiting for the entire model to be read into RAM. The first inference pays the page-in cost incrementally as the engine touches weights.
Faster warm reloads. After the first load, the kernel’s page cache holds the model’s hot pages. Re-creating a runner on the same model (e.g. after a background termination and relaunch within the same boot) is near-instant — pages stream from the page cache, not disk.
Multi-model sharing. Two processes (or two runners in one process) loading the same model file share physical pages via the page cache, with no extra RAM cost.
Graceful memory pressure. When the OS needs RAM for the foreground UI or another app, it can drop read-only model pages without writing them anywhere (they’re backed by the file). The next access re-pages them in. With anonymous heap buffers, the kernel had to choose between swapping (slow) or killing the app (worse).
Trade-offs:
First-token latency on cold pages. The first generation against a freshly-mapped model triggers page faults as the engine walks the weights. This adds disk-I/O latency to TTFT on the first call after process start. The KV cache reuse documented above compounds well here: cached prefixes skip both prefill compute and the page-fault cost for weights touched during prefill.
Storage type matters. On devices with slow eMMC / external SD storage, lazy page-in can be noticeably slower than the old eager-read flow that loaded the whole file once. Internal flash on every shipped iOS device and any modern Android device is fast enough that this isn’t visible in practice.
Opt-out available since v0.10.5. Pass useMmap = false on ModelLoadingOptions (Kotlin) or LiquidInferenceEngineOptions(useMmap: false) (Swift) to force the legacy full-read loader. Use only when mmap misbehaves on the target filesystem; the default of null/nil keeps the engine default.
This change shipped via the inference-engine vendor pin bumped in v0.10.4 (v26.02.1-79-ge5f65988dc). The default has stayed on through every subsequent pin cascade.
KV cache reuse across generations
CacheOptions (new in v0.10.4, ergonomic Swift surface in v0.10.4.3) lets the engine persist KV-cache data between generateResponse calls so requests that share a prompt prefix skip the prefill work for the shared tokens.
Disabled by default.cacheOptions is nil (Swift) / null (Kotlin) until you explicitly pass LiquidCacheOptions.enabled(path:) / ModelLoadingOptions.cacheOptions(path:). Apps that don’t opt in see no prefix reuse and no on-disk cache directory created — same behavior as 0.9.x and pre-0.10.4 builds.
Why it matters. Transformer inference has two phases: prefill (compute keys and values for every prompt token) and decode (generate one new token at a time, reusing those K/V vectors). On mobile, prefill dominates time-to-first-token for any prompt longer than a few hundred tokens. With CacheOptions enabled, a previously seen prefix is read from disk instead of recomputed — TTFT can drop from seconds to under a hundred milliseconds on cache hits. Per-token decode cost is unchanged.When it speeds things up. Anywhere the same tokens appear at the start of many requests:
Multi-turn chat with a long system prompt. Every turn reuses the system prompt and earlier turns.
RAG / retrieval-augmented generation. Many queries share the retrieved-document preamble.
Few-shot prompting. A fixed set of examples precedes every request.
Agent loops. Tool definitions, role instructions, and task scaffold are stable across iterations.
Voice assistant continuations. Conversation history grows; everything before the latest user turn is cacheable.
The cache is a bounded LRU — the engine caps cache size and evicts the least-recently-used entries automatically; you do not need to manage the directory yourself. See Model Loading → KV cache reuse for the per-platform configuration.Minimal config:
KMP target completion for leap-openai-client plus a repo-wide bytecode-hardening pass. iOS / macOS Swift surface is unchanged from v0.10.6 — this is a Kotlin/JVM ergonomics release for non-Apple consumers.New targets on leap-openai-client (PR #256):
jvm (Ktor CIO engine) — Maven Central now publishes ai.liquid.leap:leap-openai-client-jvm:0.10.7. Pure-JVM desktop / server apps can route OpenAI-compatible chat completions without dragging in Android or KMP targets. (The 0.10.0 — 0.10.6 SPM cascade only shipped Android + Apple + Linux/MinGW K/N + wasmJs metadata; the JVM slice was absent.)
The Apple slice (LeapOpenAIClient.xcframework) ships unchanged — same SSE-stream surface, same OpenAiClientConfig, same OpenRouter extra-headers support. SKIE is still not applied to this module in v0.10.7, so the Kotlin/Native exports remain the same as v0.10.6: Flow<ChatCompletionEvent> is not bridged to Swift AsyncSequence, and onEnum(of:) is not generated for ChatCompletionEvent. The next release will enable SKIE on leap-sdk-openai-client, bringing for try await over the stream, exhaustive onEnum(of:) switching, and SKIE-bundled Swift convenience inits — see the OpenAI client page for the current pinning guidance.Bytecode hardening:
The leap-sdk-jvm, leap-openai-client-jvm, leap-ui-jvm, and leap-ui-android artifacts had been silently shipping Java 17 / Java 21 bytecode against the project’s stated JVM-target-11 stance. All ten published JVM / Android slices now consistently emit class-file major version 0x37 (Java 11). Consumers running on JDK 11 — particularly long-running services and JDK-11-pinned Android Gradle builds — are no longer at risk of UnsupportedClassVersionError.
Internal: KMP build centralization (no consumer-visible API change):
Karma + headless Chrome runner for wasmJs targets centralized into the same subprojects {} block — replaces 3 per-site copies. Future modules pick up both patterns automatically.
Test coverage:
OpenAiClientTest’s seven SSE-stream + auth-header + error-event + malformed-chunk cases were promoted from androidHostTest to commonTest. They now also run on jvmTest, macosArm64Test, iosSimulatorArm64Test, linuxX64Test, mingwX64Test, and wasmJsTest.
iOS surface (unchanged from v0.10.6):The four XCFrameworks (LeapSDK, LeapModelDownloader, LeapOpenAIClient, LeapUi) ship the same Swift APIs as v0.10.6. The v0.10.6 ObjC class rename to ModelDownloader, the dual-import guard, the dynamic LeapModelDownloader framework, and the LeapDownloaderConfig() parameterless init all remain in place.
v0.10.6 — 2026-05-12
iOS ModelDownloader (the Swift class formerly known as LeapModelDownloader — see the rename note below) reaches parity with the cross-platform LeapDownloader. Callers no longer need to pair the two classes to download and load a model on Apple platforms — every entry point routes file transfer through URLSession and then hands off to the loader.New iOS API on ModelDownloader:
loadModel(modelName:, quantizationType:, options:, generationTimeParameters:, forceDownload:, downloadProgress:) — downloads (when needed) and loads in one call. The transfer registers in queryStatus, is cancellable via requestStopDownload, and continues across backgrounding when constructed with sessionConfiguration: .backgroundSessionConfiguration(withIdentifier:).
loadModel(manifestUrl:, options:, generationTimeParameters:, forceDownload:, downloadProgress:) — same flow keyed by a manifest URL.
loadSimpleModel(model: ModelSource, options:, generationTimeParameters:, downloadProgress:) — sideload from explicit paths or URLs; HTTPS sources stream through URLSession, local paths pass straight through.
forceDownload: Bool = false on all three load methods. Resolves the manifest first, then deletes the local cache, then re-downloads — a registry failure on resolve leaves the previously-working cached copy intact.
Resource-lookup helpers that previously lived only on the cross-platform LeapDownloader: getModelResourceFolder(...), getCachedManifest(...), getCachedFilePath(...), resolve(...), deleteModelFile(...).
requestDownloadModel(manifestUrl:, forceDownload:) overload for symmetry with removeModel(manifestUrl:) / queryStatus(manifestUrl:).
Breaking changes (Swift):
Class renamed: LeapModelDownloader → ModelDownloader on iOS / macOS. The Kotlin class still lives in ai.liquid.leap.downloader.LeapModelDownloader and Android consumers are unaffected; a @ObjCName(swiftName = "ModelDownloader") annotation gives the Swift export an unambiguous name distinct from the framework module’s own LeapModelDownloader name. Update Swift call sites:
- let downloader = LeapModelDownloader() // was uninstantiable from Swift in 0.10.5 due to the class-vs-module name collision+ let downloader = ModelDownloader()
Parameter labels renamed across the iOS ModelDownloader surface — model: / quantization: → modelName: / quantizationType: on every method that already existed: downloadModel(...), requestDownloadModel(...), requestStopDownload(...), queryStatus(...), removeModel(...), getModelSize(...). Every loader now uses the same labels across Swift and Kotlin — ModelDownloader (iOS, macOS), LeapModelDownloader (Android), and LeapDownloader (cross-platform) all share modelName: / quantizationType:.
LeapModelDownloader SPM library product is now single-target. It no longer bundles the LeapSDK target. Apps depending on this product must drop any direct LeapSDK SPM dependency from the same target — import LeapModelDownloader re-exports every LeapSDK Kotlin type (Conversation, ModelRunner, ChatMessage, Leap, the convenience extensions, …). Keeping both library products on the same target double-bundles the inference engine dylibs and triggers a build-time #error from the LMD umbrella header (see “dual-import guard” below); the LeapUI library product still bundles LeapSDK because LeapUI does not re-emit those types in its ObjC binding.
LeapModelDownloader.xcframework is now a dynamic framework. It was a static archive in 0.10.5. SPM applies Embed & Sign automatically; manual integrators must add the framework with “Embed & Sign” instead of “Do Not Embed”. The shipped XCFramework now also bundles the inference engine dylibs (libinference_engine.dylib, libinference_engine_llamacpp_backend.dylib, libie_zip.dylib) under Frameworks/ with an @loader_path/Frameworks LC_RPATH — consumers using LMD on its own no longer need LeapSDK.framework/Frameworks on their search path.
Dual-import build-time guard. LMD’s umbrella header carries a __has_include(<LeapSDK/LeapSDK.h>) && !defined(LEAP_DUAL_IMPORT_ALLOW) check that fires #error at the consumer’s preprocessing time when both LeapSDK and LeapModelDownloader frameworks are reachable in the same target. To opt out for legitimate combinations (e.g. transitive linkage via LeapUI), add LEAP_DUAL_IMPORT_ALLOW=1 to OTHER_CFLAGS.
New Swift conveniences:
ModelDownloader(), ModelDownloader(sessionConfiguration:), ModelDownloader(config:) — Kotlin/Native ObjC export strips default-argument metadata, so 0.10.5 forced Swift callers to pass every parameter (and LeapDownloaderConfig has seven). These new SKIE-bundled convenience inits restore the parameterless / single-arg forms.
LeapDownloaderConfig() parameterless convenience init mirroring the Kotlin defaults (saveDir = "leap_models", validateSha256 = true, etc.). Same rationale — LeapDownloaderConfig is a Kotlin data class with seven defaulted fields that the ObjC export couldn’t carry through.
Behavior changes:
requestDownloadModel(forceDownload: false) now short-circuits when a cached manifest already exists and every resource referenced by that manifest is present on disk — matches both the Android downloader’s idempotent-call semantics and what queryStatus(...) already reports. Earlier 0.10.5 builds would short-circuit on the manifest alone, leaving the caller stuck if any resource file had been removed. Pass forceDownload: true to re-download on top of a cache.
Cached-file lookup uses Ktor URL parsing instead of substring slicing, so URLs with fragments or query strings now produce the same filename the loader expects (getCachedFilePath was previously brittle for those shapes).
Fixes:
getAvailableDiskSpace() previously returned null on every Apple platform because the internal NSFileManager.attributesOfFileSystem(forPath:)[.systemFreeSize] extraction cast through as? Long (Kotlin) which never matches the bridged NSNumber. Now goes through NSNumber.longLongValue and reports the real free-space figure.
Other changes:
Options on the new load methods take LiquidInferenceEngineManifestOptions? (the Swift-friendly type already used by Leap.load), with toModelLoadingOptions() / toGenerationTimeParameters() conversion at the boundary — no separate KMP options class needed from Swift.
Internal: the iOS class uses kotlin.experimental.ExperimentalObjCName (stable in our Kotlin 2.3.20 baseline but still formally experimental).
No public-API changes for Android or non-Apple Kotlin/Native targets.
v0.10.5 — 2026-05-11
Headline additions: Android Leap Model Service for cross-app model sharing, the useMmap knob on ModelLoadingOptions, and a parameter-name cleanup on LeapDownloader.loadModel so it matches LeapModelDownloader.loadModel.Breaking changes (Kotlin):
ModelLoadingOptions.cacheDir: String? → cacheOptions: EngineOptions.CacheOptions? — KV cache configuration moves to a bounded-LRU CacheOptions value with explicit enabled master switch, per-tier caps (maxEntriesDisk, maxEntriesMemory, maxBytesMemory), and optional diskDisabled = true for memory-only mode. Migrate via the ModelLoadingOptions.cacheOptions(path = ...) factory (preserves the historical 40-entry disk budget and sets enabled = true). Constructing a raw CacheOptions requires enabled = true to enable the cache — a positive maxEntries alone is no longer sufficient.
LeapDownloader.loadModel(modelName, quantizationSlug, modelLoadingOptions, …) → loadModel(modelName, quantizationType, options, …) — parameter renames bring LeapDownloader in line with LeapModelDownloader. The same rename applies to loadSimpleModel(model, modelLoadingOptions, …) → loadSimpleModel(model, options, …) and loadModelFromManifestUrl(…). Swift sites that called downloader.loadModel(modelName:, quantizationSlug:, modelLoadingOptions:) need to swap to quantizationType: / options: after upgrading.
progress is now nullable (progress: ((ProgressData) -> Unit)? = null) — pass null to opt out (was an empty-lambda default).
New features:
ModelLoadingOptions.useMmap: Boolean? = null — exposes the engine’s use_mmap toggle to Kotlin/Swift callers. null (default) defers to the engine default of true. Set false only on filesystems where mmap misbehaves (some Android scoped-storage paths, certain network mounts). On Swift, LiquidInferenceEngineOptions gained a matching .with(useMmap:) builder. Previously mmap could not be disabled from the SDK.
Leap Model Service (Android) — leap-model-service is a new optional Android service that hosts loaded models in its own process and lets multiple client apps share them. Apps using LeapModelDownloader.loadModel(...) route through the service transparently when it’s installed on the device; otherwise they fall back to in-process loading. Per-UID session quotas, persistent foreground notification, disk-backed KV cache reuse across cold starts, and AIDL-routed registerFunction(s). Pass forceLocal = true on LeapModelDownloader.loadModel(...) to bypass the service for testing. See Model Loading for the routing model.
Service-side load progress — when routing through the model service, LeapModelDownloader.loadModel’s progress callback now fires for service-side downloads too (was previously local-path-only).
Fixes / refresh:
Apple LeapModelDownloader internal slot names switched from quantizationSlug → quantizationType for consistency. Public Swift label names (model: / quantization:) are unchanged.
Vendor liquid.h header refresh for Linux/MinGW K/N targets.
v0.10.4.5 — 2026-05-08
Engine ABI fix release. SPM consumers should bump to this version.
Engine pin advanced to v26.02.1-146-g777faf0dbb — fixes a K/N + Linux free(): invalid pointer SIGABRT in liquid_string_destroy (the FFI helper was freeing the wrong pointer slot).
Linux runtime smoke test now asserts the engine reports failure on a missing model path, guarding against silent-success regressions.
NativeLibLoader cleanup: stdout warnings moved to System.err; loader stays kotlin-stdlib-only.
v0.10.4.4 — 2026-05-07
K/N link-time --allow-shlib-undefined fix for Linux consumers. No API changes.
v0.10.4.3 — 2026-05-07
iOS/macOS Swift convenience surface for cacheOptions:
LiquidInferenceEngineManifestOptions(cacheOptions: ..., contextSize: 4096) now accepts native Swift types (previously the convenience init dropped cacheOptions and forced consumers to the verbose Obj-C designated init).
New with(cacheOptions:) builders on LiquidInferenceEngineOptions and LiquidInferenceEngineManifestOptions.
New LiquidCacheOptions.enabled(path:) static factory — Swift analog of ModelLoadingOptions.cacheOptions(path:).
(v0.10.4.2 was staged to Sonatype but never released; superseded by 0.10.4.3.)
v0.10.4.1 — 2026-05-07
Vendor pin refresh — bumps the inference engine to v26.02.1-142-gb4aa080538. Adds Strategy B chain-prefix replay for cold/warm bit-determinism and generalizes the Android backend native loader to Linux and Windows desktop. No public API changes.
v0.10.4 — 2026-05-06
Bounded-LRU CacheOptions API across JVM, Android, Kotlin/Native, Apple, and wasmJs.
use_mmap=true is now the engine default (via vendored IE pin v26.02.1-79+). Model weights are memory-mapped instead of read(2)-ed into a heap buffer. See Memory-mapped model loading by default above for the mobile performance impact.
K/N Linux link fix (--allow-shlib-undefined for libinference_engine.so against modern glibc).
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Liquid AI Docs","description":"Documentation for Liquid AI Foundation Models (LFM)","colors":{"primary":"#7c3aed","light":"#ac8dff","dark":"#7c3aed"},"logo":{"light":"https://mintcdn.com/liquidai/GZ4byic0rSMkhisf/logo/light.svg?fit=max\u0026auto=format\u0026n=GZ4byic0rSMkhisf\u0026q=85\u0026s=38de6a520e556114d9bdd76300d71c58","dark":"https://mintcdn.com/liquidai/GZ4byic0rSMkhisf/logo/dark.svg?fit=max\u0026auto=format\u0026n=GZ4byic0rSMkhisf\u0026q=85\u0026s=87de315938749fc0bef458d3e25059a7","href":"/lfm/models/complete-library"},"favicon":"https://mintcdn.com/liquidai/GZ4byic0rSMkhisf/favicon.svg?fit=max\u0026auto=format\u0026n=GZ4byic0rSMkhisf\u0026q=85\u0026s=afa07b83909db8009690f791e9bd520b","appearance":{"default":"light"},"background":{"color":{"light":"#ffffff","dark":"#0a0a0a"}},"navbar":{"links":[{"icon":"discord","href":"https://discord.gg/DFU3WQeaYD","label":"Discord"},{"href":"https://github.com/Liquid4All/cookbook","label":"Cookbook","type":"github"}],"primary":{"type":"button","label":"Try our API","href":"https://console.liquid.ai/?utm_source=docs\u0026utm_medium=navbar\u0026utm_campaign=try_our_api"}},"footer":{"socials":{"github":"https://github.com/Liquid4All/cookbook","discord":"https://discord.gg/DFU3WQeaYD","website":"https://liquid.ai"}},"seo":{"organization":{"name":"Liquid AI","url":"https://www.liquid.ai","logo":"https://docs.liquid.ai/logo/light.svg","sameAs":["https://huggingface.co/LiquidAI","https://github.com/Liquid4All","https://x.com/liquidai","https://www.linkedin.com/company/liquid-ai-inc","https://www.youtube.com/channel/UClzRQA8Un3AJnlD6h1hv6fA"]},"indexing":"all"},"fonts":{"family":"Inter"},"styling":{"codeblocks":{"theme":{"light":"github-light","dark":"github-dark"}},"latex":false},"banner":{"content":"🚀 New: LFM3 — text, vision, audio, omni, and decision models on one new backbone! [Learn more →](/lfm/models/complete-library)","dismissible":true},"contextual":{"options":["copy","chatgpt","claude","cursor","vscode"],"display":"header"},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"liquidai","hasAudioNarration":false,"actualSubdomain":"liquidai","customDomains":["docs.liquid.ai"],"gitSource":{"type":"github","owner":"liquid4all","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"feedback":{"thumbs":true,"edits":true,"issues":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"DISABLED"}},"buildId":"6af77bd588757915d6787445","clientVersion":"0.0.4138","searchFilterCounts":[{"language":"default","tag":"LFM","count":88},{"language":"default","tag":"API reference","count":48},{"language":"default","tag":"Examples","count":46},{"language":"default","tag":"API","count":18},{"language":"default","tag":"Models","count":15},{"language":"default","tag":"Endpoints","count":13},{"language":"default","tag":"Edge Inference","count":8},{"language":"default","tag":"Laptop Examples","count":8},{"language":"default","tag":"Fine-tuning","count":6},{"language":"default","tag":"Help","count":6}]},"assistantConfig":{"enableStarterQuestions":false,"deflection":{"enabled":true,"email":"support@liquid.ai","showHelpButton":true}},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"/* cyrillic-ext */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrodmgPn.woff2) format('woff2');\n unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;\n}\n/* cyrillic */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrMdmgPn.woff2) format('woff2');\n unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;\n}\n/* symbols2 */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFg08vz7ehw.woff2) format('woff2');\n unicode-range: U+2000-2001, U+2004-2008, U+200A, U+23B8-23BD, U+2500-259F;\n}\n/* vietnamese */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrgdmgPn.woff2) format('woff2');\n unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;\n}\n/* latin-ext */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrkdmgPn.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrcdmg.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n/* cyrillic-ext */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrodmgPn.woff2) format('woff2');\n unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;\n}\n/* cyrillic */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrMdmgPn.woff2) format('woff2');\n unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;\n}\n/* symbols2 */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFg08vz7ehw.woff2) format('woff2');\n unicode-range: U+2000-2001, U+2004-2008, U+200A, U+23B8-23BD, U+2500-259F;\n}\n/* vietnamese */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrgdmgPn.woff2) format('woff2');\n unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;\n}\n/* latin-ext */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrkdmgPn.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 500;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrcdmg.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n/* cyrillic-ext */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrodmgPn.woff2) format('woff2');\n unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;\n}\n/* cyrillic */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrMdmgPn.woff2) format('woff2');\n unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;\n}\n/* symbols2 */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFg08vz7ehw.woff2) format('woff2');\n unicode-range: U+2000-2001, U+2004-2008, U+200A, U+23B8-23BD, U+2500-259F;\n}\n/* vietnamese */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrgdmgPn.woff2) format('woff2');\n unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;\n}\n/* latin-ext */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrkdmgPn.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'Geist Mono';\n font-style: normal;\n font-weight: 600;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/geistmono/v6/or3nQ6H-1_WfwkMZI_qYFrcdmg.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n/* vietnamese */\n@font-face {\n font-family: 'Newsreader';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/newsreader/v26/cY9qfjOCX1hbuyalUrK49dLac06G1ZGsZBtoBCzBDXXD9JVF438weI_wBOZFDjA.woff2) format('woff2');\n unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;\n}\n/* latin-ext */\n@font-face {\n font-family: 'Newsreader';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/newsreader/v26/cY9qfjOCX1hbuyalUrK49dLac06G1ZGsZBtoBCzBDXXD9JVF438weI_wBeZFDjA.woff2) format('woff2');\n unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;\n}\n/* latin */\n@font-face {\n font-family: 'Newsreader';\n font-style: normal;\n font-weight: 400;\n font-display: swap;\n src: url(/_mintlify/assets/fonts/google/s/newsreader/v26/cY9qfjOCX1hbuyalUrK49dLac06G1ZGsZBtoBCzBDXXD9JVF438weI_wC-ZF.woff2) format('woff2');\n unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;\n}\n.tabs,.tab-container{flex-direction:column!important}:root:not(.dark) body>div.antialiased{color:var(--lfm-fg)!important}.dark body>div.antialiased{color:var(--lfm-fg)!important}.navbar-link a[href*=\"discord\"] img,a[href*=\"discord.gg\"] img{opacity:0.6}.navbar-link a[href*=\"discord\"]:hover,a[href*=\"discord.gg\"]:hover{color:var(--lfm-accent)!important}.navbar-link a[href*=\"discord\"]:hover img,a[href*=\"discord.gg\"]:hover img{opacity:1;filter:brightness(0) saturate(100%) invert(23%) sepia(69%) saturate(7402%) hue-rotate(259deg) brightness(104%) contrast(86%)}.dark .navbar-link a[href*=\"discord\"]:hover img,.dark a[href*=\"discord.gg\"]:hover img{filter:brightness(0) saturate(100%) invert(63%) sepia(5%) saturate(6230%) hue-rotate(208deg) brightness(94%) contrast(148%)}#banner{--color-white: var(--lfm-fg-inverse);background-color:var(--lfm-fg)!important}#banner a{text-decoration-color:color-mix(in srgb, var(--lfm-fg-inverse) 50%, transparent)!important}#banner a:hover{text-decoration-color:var(--lfm-fg-inverse)!important}#banner button:hover{background-color:color-mix(in srgb, var(--lfm-fg-inverse) 12%, transparent)!important}#navbar li.navbar-link a{padding:6px!important}#navbar li.navbar-link a>span.truncate{position:absolute!important;width:1px!important;height:1px!important;margin:-1px!important;padding:0!important;overflow:hidden!important;clip:rect(0, 0, 0, 0)!important;white-space:nowrap!important;border:0!important}#navbar li.navbar-link a[href^=\"https://github.com/\"]>span:not(.truncate){display:none!important}#navbar li.navbar-link a{color:var(--lfm-muted)!important}#navbar li.navbar-link a:hover{color:var(--lfm-accent)!important}#navbar li.navbar-link a svg[style*=\"mask-image\"]{background-color:currentColor!important}#topbar-cta-button a>span[class*=\"bg-primary\"]{background-color:var(--lfm-fg)!important;opacity:1!important;transition:background-color 0.15s ease!important}#topbar-cta-button a:hover>span[class*=\"bg-primary\"]{background-color:var(--lfm-accent)!important}#topbar-cta-button a .text-white,#topbar-cta-button a svg{color:var(--lfm-fg-inverse)!important}#mobile-nav>button[aria-label=\"Close navigation\"]{left:auto!important;right:1rem!important;margin-left:0!important;width:2.75rem!important;height:2.75rem!important}#mobile-nav:not([data-ending-style])>button[aria-label=\"Close navigation\"]{opacity:1!important;pointer-events:auto!important}#mobile-nav [data-component-part=\"scroll-area-viewport\"]{padding-top:0!important}#mobile-nav div:has(>a>.nav-logo){position:sticky;top:0;z-index:1;display:grid!important;grid-template-columns:minmax(0, 1fr) auto;gap:0.5rem;min-height:3.75rem;padding-top:1rem;padding-right:3.25rem;background-color:var(--lfm-bg)}#mobile-nav .nav-logo{max-width:100%!important;max-height:26px;height:auto!important}:is(#feedback-thumbs-up,#feedback-thumbs-down)[data-lfm-feedback-acknowledged]{color:var(--lfm-fg)!important;border-color:var(--lfm-fg)!important;background-color:var(--lfm-surface)!important}:is(#feedback-thumbs-up,#feedback-thumbs-down)[data-lfm-feedback-acknowledged]>svg{display:none!important}:is(#feedback-thumbs-up,#feedback-thumbs-down)[data-lfm-feedback-acknowledged]::before{content:\"\";width:1rem;height:1rem;flex-shrink:0;background-color:currentColor;mask:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m5 12 4 4L19 6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\") center / contain no-repeat}.card-group{overflow:visible!important;contain:none!important;padding:4px!important}[class*=\"block\"][class*=\"rounded\"][class*=\"border\"]:not(.use-cases *){border-width:1px!important;border-style:solid!important}@layer utilities{.mdx-content .card:not(.use-cases *):hover[class]{border-color:var(--lfm-fg)!important}}.mdx-content .card:not(.use-cases *):hover [data-component-part=\"card-title\"],.mdx-content .card:not(.use-cases *):hover h2.not-prose{color:var(--lfm-fg)!important}.mdx-content .card a[href^=\"http\"] div:has(>svg>use[href*=\"ExternalLink\"]){display:block!important;color:var(--lfm-muted)!important}.mdx-content .card:not(.use-cases *):hover svg:not([data-component-part=\"card-icon\"] svg){color:var(--lfm-fg)!important}:root:not(.dark) .card-group a[class*=\"block\"] svg:not([class*=\"arrow\"]):not(:has(use[href*=\"ExternalLink\"])){background-color:var(--lfm-accent)!important}:root:not(.dark) .mdx-content [class*=\"card\"] svg:not([class*=\"arrow\"]):not(:has(use[href*=\"ExternalLink\"])),:root:not(.dark) .mdx-content a[class*=\"block\"][class*=\"border\"] svg:not([class*=\"arrow\"]):not(:has(use[href*=\"ExternalLink\"])){background-color:var(--lfm-accent)!important}:root:not(.dark) .mdx-content [class*=\"card\"] [style*=\"mask-image\"],:root:not(.dark) .mdx-content a[class*=\"block\"][class*=\"border\"] [style*=\"mask-image\"]{background-color:var(--lfm-accent)!important;color:var(--lfm-accent)!important}:is(#sidebar-content,#mobile-nav) li[data-active]:not(:has(li[data-active]))>:is(a,button){color:var(--lfm-fg)!important;background-color:var(--lfm-surface)!important}:is(#sidebar-content,#mobile-nav) li[data-active]:not(:has(li[data-active]))>:is(a,button) svg{color:var(--lfm-fg)!important}:is(#sidebar-content,#mobile-nav) li[data-active]:not(:has(li[data-active]))>:is(a,button) [style*=\"mask-image\"]{background-color:var(--lfm-fg)!important}#sidebar-content li>a:hover,#sidebar-content li>button:hover{color:var(--lfm-fg)!important}.mdx-content{contain:none!important;overflow:visible!important}code,pre,kbd,samp{font-family:\"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, monospace!important}:root{--lfm-fs-xs: 12px;--lfm-fs-sm: 13px;--lfm-fs-base: 15px;--lfm-fs-lg: 16px;--lfm-fs-xl: 20px;--lfm-fs-2xl: 32px;--lfm-font-serif: \"Iowan Old Style\", \"Iowan Old Style BT\", \"ITC Iowan Old Style\", \"Newsreader\", \"Palatino\", Georgia,\n ui-serif, serif}:root{--lfm-radius: 2px}:root{--lfm-accent: #7c3aed;--lfm-accent-wash: #f2ecff;--lfm-bg: #ffffff;--lfm-title: #000000;--lfm-fg: #18181b;--lfm-fg-inverse: #fafafa;--lfm-muted: #71717a;--lfm-faint: #a1a1aa;--lfm-surface: #f4f4f5;--lfm-subtle: #f4f4f5;--lfm-border: #00000014;--lfm-border-strong: #0000001a;--lfm-success: #22c55e;--lfm-success-strong: #16a34a;--lfm-link: color-mix(in srgb, var(--lfm-fg) 42%, var(--lfm-accent));--lfm-link-hover: var(--lfm-accent);--lfm-ring: var(--lfm-fg)}:root.dark{--lfm-accent: #ac8dff;--lfm-accent-wash: #2a1d4a;--lfm-bg: #0a0a0a;--lfm-title: #ffffff;--lfm-fg: #fafafa;--lfm-fg-inverse: #0a0a0a;--lfm-muted: #a1a1aa;--lfm-faint: #71717a;--lfm-surface: #27272a;--lfm-subtle: #27272a;--lfm-border: #ffffff21;--lfm-border-strong: #ffffff26;--lfm-success: #4ade80;--lfm-success-strong: #86efac;--lfm-link: color-mix(in srgb, var(--lfm-fg) 42%, var(--lfm-accent));--lfm-link-hover: var(--lfm-accent);--lfm-ring: var(--lfm-fg)}:focus-visible{outline-color:var(--lfm-ring)!important}*,*::before,*::after{border-radius:var(--lfm-radius)!important}[data-component-part=\"step-indicator\"],[data-component-part=\"scroll-area-thumb\"]{border-radius:revert-layer!important}@layer utilities{.code-block-background[data-component-part=\"code-block-root\"][class]{border-radius:var(--lfm-radius)!important}}[data-badge]{--color-bg: transparent !important;--color-text: var(--lfm-fg) !important;outline:1px solid var(--lfm-border)!important;outline-offset:-1px!important}[data-badge][data-color=\"green\"]{--color-bg: var(--lfm-accent-wash) !important;--color-text: var(--lfm-accent) !important;outline-color:transparent!important}#page-title{color:var(--lfm-title)!important;font-size:var(--lfm-fs-2xl)!important;line-height:1.2!important;font-family:var(--lfm-font-serif)!important;font-weight:400!important;letter-spacing:-0.023em!important}#page-context-menu button{height:24px!important;padding-top:0!important;padding-bottom:0!important;color:var(--lfm-faint)!important;background-color:transparent!important;border-color:var(--lfm-border)!important;font-size:var(--lfm-fs-xs)!important;transition:color 0.15s ease!important}#page-context-menu-button{padding-left:8px!important;padding-right:8px!important}#page-context-menu-button>div{gap:6px!important;font-size:var(--lfm-fs-xs)!important;font-weight:500!important;line-height:1!important}#page-context-menu button svg{width:13px!important;height:13px!important}#page-context-menu button[aria-haspopup=\"menu\"]{width:24px!important;justify-content:center!important}#page-context-menu button:hover,#page-context-menu button[aria-expanded=\"true\"]{color:var(--lfm-fg)!important}#header:has(.eyebrow)>div:first-child>div:has(>#page-context-menu){position:static!important}#header:has(.eyebrow)>div:first-child #page-context-menu{position:absolute!important;top:0!important;right:0!important}@container page-header (min-width: 400px){#header:has(.eyebrow)>div:first-child #page-context-menu{display:flex!important}#header:has(.eyebrow)>#page-context-menu{display:none!important}}[data-base-ui-portal] [role=\"menu\"] [role=\"menuitem\"]:has(.text-xs) .font-medium{font-size:var(--lfm-fs-sm)!important;font-weight:400!important}#header .prose{font-size:var(--lfm-fs-lg)!important;line-height:1.5!important}.eyebrow{font-size:var(--lfm-fs-xs)!important;font-weight:500!important}#header .eyebrow{margin-bottom:14px!important}@media (min-width: 1024px){#header:has(.eyebrow){margin-top:-5px!important}#header:not(:has(.eyebrow)){margin-top:29px!important}}:root{--lfm-rail-offset: 40px}#table-of-contents{top:-1.5px!important}#table-of-contents>[data-component-part=\"scroll-area-viewport\"]{padding-top:calc(2.5rem + var(--lfm-rail-offset))!important}.panel{position:relative!important;top:calc(var(--lfm-rail-offset) - 2px)!important}#header .text-lg.prose{margin-top:16px!important}#content-area #content.mdx-content{margin-top:40px!important}#content.mdx-content,.mdx-content .prose{--tw-prose-body: var(--lfm-fg);--tw-prose-invert-body: var(--lfm-fg);color:var(--lfm-fg)!important}#content.mdx-content,.mdx-content [data-component-part=\"tab-content\"],.mdx-content [data-component-part=\"accordion-content\"],.mdx-content [data-component-part=\"step-content\"]{font-size:var(--lfm-fs-base)!important;line-height:1.65!important}.mdx-content [data-component-part=\"accordion-content\"]{padding-top:8px!important}.mdx-content h2{font-size:var(--lfm-fs-xl)!important;line-height:1.3!important}.mdx-content>h2:not(:first-child){margin-top:40px!important}.mdx-content h3{font-size:var(--lfm-fs-lg)!important;line-height:1.3!important}.mdx-content code:not(pre code){font-size:0.93em!important}pre{font-size:var(--lfm-fs-sm)!important;line-height:1.6!important}.mdx-content [data-component-part=\"card-title\"]{font-size:var(--lfm-fs-base)!important}.mdx-content [data-component-part=\"card-content\"]{font-size:var(--lfm-fs-sm)!important;line-height:1.5!important}.mdx-content [data-component-part=\"card-content\"],.mdx-content [data-component-part=\"card-content\"] .prose{--tw-prose-body: var(--lfm-muted);--tw-prose-invert-body: var(--lfm-muted);color:var(--lfm-muted)!important}.model-cards .card div:has(>[data-component-part=\"card-title\"]){display:flex!important;flex-direction:column!important}.model-cards [data-component-part=\"card-content\"]{display:contents!important}.model-cards [data-component-part=\"card-content\"]>:first-child{order:-1;display:flex!important;align-items:center!important;justify-content:space-between!important;gap:0.5rem!important;margin:0 0 0.75rem!important;font-family:\"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, monospace!important;font-size:var(--lfm-fs-xs)!important;letter-spacing:0.04em!important;text-transform:uppercase!important;color:var(--lfm-muted)!important}.model-cards [data-component-part=\"card-content\"]>:first-child>span{font-family:Inter, -apple-system, system-ui, sans-serif!important;letter-spacing:normal!important;text-transform:none!important}.model-cards [data-component-part=\"card-title\"]{font-family:var(--lfm-font-serif)!important;font-size:var(--lfm-fs-xl)!important;font-weight:400!important;line-height:1.2!important;letter-spacing:-0.015em!important}.model-cards [data-component-part=\"card-content\"]>:last-child{margin:0.375rem 0 0!important}.sidebar-group a,.sidebar-group button{font-size:var(--lfm-fs-sm)!important;line-height:1.4!important}.sidebar-group-header{font-size:var(--lfm-fs-xs)!important}#sidebar-content .sidebar-group-header,#mobile-nav .sidebar-group-header{display:none!important}.sidebar-group>li[data-title]>button{color:var(--lfm-fg)!important;font-weight:500!important}.sidebar-group>li+li{margin-top:6px!important}.sidebar-group>li[data-title]>ul{padding-left:16px!important}.nav-tabs-item,.navbar-link a{font-size:var(--lfm-fs-sm)!important}#navbar-transition{border-bottom-width:0!important}@media (min-width: 1280px){#content-container:has(#api-playground-2-operation-page) [data-layout-item=\"side-panel\"]{max-width:24rem!important}#content-container:has(#api-playground-2-operation-page) [data-layout-item=\"side-panel\"]>div{width:24rem!important}#content-container:has(#api-playground-2-operation-page) [data-layout-item=\"side-panel\"]{margin-top:-5px!important;top:calc(9.5rem - 5px)!important}html[data-banner-state=\"visible\"] #content-container:has(#api-playground-2-operation-page) [data-layout-item=\"side-panel\"]{top:calc(12rem - 5px)!important}#content-container:has(#api-playground-2-operation-page) #content-area{width:calc(100% - 24rem)!important}}#table-of-contents{font-size:var(--lfm-fs-sm)!important;line-height:1.5!important}#table-of-contents-layout{width:17rem!important;padding-left:4rem!important}#table-of-contents{width:13rem!important}#table-of-contents nav>h2{font-size:var(--lfm-fs-xs)!important}#table-of-contents .toc-item a{line-height:20px!important;padding-top:3px!important;padding-bottom:3px!important}#table-of-contents-content{margin-top:10px!important}.lg\\:overflow-x-clip{overflow:visible!important}body>div.antialiased{overflow:visible!important}@media (max-width: 1279px){.panel{display:none!important}}.panel{width:13rem!important;margin-left:1.5rem!important;font-size:var(--lfm-fs-sm)!important}.panel ul{list-style:none!important;padding-left:0!important;margin:0!important}.panel li{margin-bottom:0.75rem!important}.panel li a{color:inherit!important;font-weight:inherit!important;text-decoration:none!important;background-image:none!important;border-bottom:0!important;padding-bottom:0!important;transition:color 0.2s ease!important}.panel li a::after{content:\"↗\"!important;font-size:0.85em!important;color:var(--lfm-muted)!important;margin-left:0.35em!important;transition:transform 0.15s ease, color 0.15s ease!important;display:inline-block!important}.panel li a:hover{color:var(--lfm-accent)!important}.panel li a:hover::after{color:var(--lfm-accent)!important;transform:translate(2px, -2px)!important}.eyebrow{color:var(--lfm-faint)!important}.use-cases .card-group{padding:0!important;row-gap:0.5rem!important;column-gap:0.5rem!important}.use-cases .card{margin:0!important;border:none!important;border-color:transparent!important;border-width:0!important;border-radius:var(--lfm-radius)!important;background-color:var(--lfm-surface)!important;overflow:visible!important;--tw-ring-color: transparent !important;--tw-ring-offset-color: transparent !important;--tw-ring-shadow: none !important;box-shadow:none!important;outline:none!important}.use-cases [data-component-part=\"card-content-container\"]{padding:1rem 0.9rem!important;display:grid!important;grid-template-columns:auto 1fr!important;align-items:start!important;column-gap:0.45rem!important;row-gap:0!important}.use-cases{--lfm-tile-title-lh: calc(var(--lfm-fs-base) * 1.3)}.use-cases [data-component-part=\"card-icon\"]{display:flex!important;align-items:center!important;height:var(--lfm-tile-title-lh)!important;transform:scale(0.7)!important;transform-origin:left center!important;margin-right:-0.35rem!important}.use-cases [data-component-part=\"card-icon\"] svg{background-color:var(--lfm-muted)!important}.use-cases [data-component-part=\"card-title\"]{margin-top:0!important;line-height:var(--lfm-tile-title-lh)!important;color:var(--lfm-fg)!important}.use-cases [data-component-part=\"card-content\"]{margin-top:0.25rem!important;color:var(--lfm-muted)!important;line-height:1.35!important}.capabilities ul{margin:0.5rem 0!important}.capabilities li{margin-bottom:0.25rem!important}.capabilities p,.capabilities li{color:inherit!important}.capabilities strong{font-weight:600!important;color:inherit!important}.callout{border-width:1px!important}.callout[data-callout-type=\"tip\"],.callout[data-callout-type=\"note\"],.callout[data-callout-type=\"info\"],.callout[data-callout-type=\"check\"]{background-color:var(--lfm-surface)!important;border-color:transparent!important}.callout[data-callout-type=\"tip\"] [data-component-part=\"callout-content\"],.callout[data-callout-type=\"note\"] [data-component-part=\"callout-content\"],.callout[data-callout-type=\"info\"] [data-component-part=\"callout-content\"],.callout[data-callout-type=\"check\"] [data-component-part=\"callout-content\"]{color:var(--lfm-fg)!important}.callout[data-callout-type=\"tip\"] [data-component-part=\"callout-icon\"] svg,.callout[data-callout-type=\"note\"] [data-component-part=\"callout-icon\"] svg,.callout[data-callout-type=\"info\"] [data-component-part=\"callout-icon\"] svg{color:var(--lfm-accent)!important}.callout .code-block{--lfm-subtle: var(--lfm-bg)}.callout [data-component-part=\"callout-content\"] a{-webkit-text-fill-color:var(--lfm-link)!important}.callout [data-component-part=\"callout-content\"] a:hover{-webkit-text-fill-color:var(--lfm-link-hover)!important}article a:not([class*=\"block\"]):not([aria-label=\"Navigate to header\"]):not(table a):not(.back-button):not([style*=\"background\"]):not(.colab-link a),[role=\"main\"] a:not([class*=\"block\"]):not([aria-label=\"Navigate to header\"]):not(table a):not(.back-button):not([style*=\"background\"]):not(.colab-link a),.prose a:not([class*=\"block\"]):not([aria-label=\"Navigate to header\"]):not(table a):not(.back-button):not([style*=\"background\"]):not(.colab-link a){color:var(--lfm-link)!important;font-weight:400!important;text-decoration:none!important;background-image:none!important;border-bottom:0!important;padding-bottom:0!important;text-decoration-thickness:1px!important;text-underline-offset:5px!important;transition:color 0.2s ease, text-decoration-color 0.2s ease!important}article a:not([class*=\"block\"]):not([aria-label=\"Navigate to header\"]):not(table a):not(.back-button):not([style*=\"background\"]):not(.colab-link a):hover,[role=\"main\"] a:not([class*=\"block\"]):not([aria-label=\"Navigate to header\"]):not(table a):not(.back-button):not([style*=\"background\"]):not(.colab-link a):hover,.prose a:not([class*=\"block\"]):not([aria-label=\"Navigate to header\"]):not(table a):not(.back-button):not([style*=\"background\"]):not(.colab-link a):hover{color:var(--lfm-link-hover)!important;text-decoration-line:underline!important}.mdx-content a[style*=\"background\"]{border-bottom:0!important}article :is(h1,h2,h3,h4,h5,h6) a[href^=\"#\"],[role=\"main\"] :is(h1,h2,h3,h4,h5,h6) a[href^=\"#\"],.prose :is(h1,h2,h3,h4,h5,h6) a[href^=\"#\"],article a[href^=\"#\"][aria-label*=\"link\"i],[role=\"main\"] a[href^=\"#\"][aria-label*=\"link\"i],.prose a[href^=\"#\"][aria-label*=\"link\"i]{background-image:none!important;background-size:0 0!important;padding-bottom:0!important;text-decoration:none!important}table{font-size:var(--lfm-fs-sm)!important;border-collapse:collapse!important;border-spacing:0!important;width:100%!important;max-width:100%!important;margin:1em 0!important;table-layout:auto!important}table thead th{padding:0.75rem 1rem!important;font-weight:600!important;text-align:left!important}table tbody td{padding:0.75rem 1rem!important;vertical-align:middle!important}table tbody tr{border-bottom:1px solid var(--lfm-border)!important}table:not(:has(thead th:nth-child(6))) td,table:not(:has(thead th:nth-child(6))) th{width:auto!important;overflow:visible!important;text-overflow:clip!important;white-space:normal!important;text-align:left!important;padding:0.75rem 1rem!important}table:not(:has(thead th:nth-child(6))){table-layout:auto!important}table:has(thead th:nth-child(6):not(:nth-child(7))){table-layout:fixed!important;margin:0!important}table:has(thead th:nth-child(6):not(:nth-child(7))) td:first-child,table:has(thead th:nth-child(6):not(:nth-child(7))) th:first-child{width:45%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}table:has(thead th:nth-child(6):not(:nth-child(7))) td:nth-child(2),table:has(thead th:nth-child(6):not(:nth-child(7))) th:nth-child(2),table:has(thead th:nth-child(6):not(:nth-child(7))) td:nth-child(3),table:has(thead th:nth-child(6):not(:nth-child(7))) th:nth-child(3),table:has(thead th:nth-child(6):not(:nth-child(7))) td:nth-child(4),table:has(thead th:nth-child(6):not(:nth-child(7))) th:nth-child(4),table:has(thead th:nth-child(6):not(:nth-child(7))) td:nth-child(5),table:has(thead th:nth-child(6):not(:nth-child(7))) th:nth-child(5){width:8%!important;text-align:center!important;padding:0.5rem 0!important}table:has(thead th:nth-child(6):not(:nth-child(7))) td:nth-child(6),table:has(thead th:nth-child(6):not(:nth-child(7))) th:nth-child(6){width:15%!important;text-align:center!important;padding:0.5rem 0!important;white-space:nowrap!important}table:has(thead th:nth-child(6):not(:nth-child(7))) thead tr{background:transparent!important;border-top:0!important}table:has(thead th:nth-child(6):not(:nth-child(7))) thead th{color:var(--lfm-fg)!important}table:has(thead th:nth-child(6):not(:nth-child(7))) tbody tr:has(td:first-child strong){background:var(--lfm-surface)!important}table:has(thead th:nth-child(6):not(:nth-child(7))) tbody tr:has(td:nth-child(2):empty):not(:has(strong)){background-color:var(--lfm-surface)!important}table:has(thead th:nth-child(6):not(:nth-child(7))) tbody tr:has(td:nth-child(2):empty):not(:has(strong)) td{background-color:var(--lfm-surface)!important;padding:0.35rem 0.5rem!important}table:has(thead th:nth-child(6):not(:nth-child(7))) tbody tr:has(td:nth-child(2):empty):not(:has(strong)) td:first-child{text-align:left!important;font-size:var(--lfm-fs-xs)!important;color:var(--lfm-muted)!important;padding-left:1rem!important}table:has(thead th:nth-child(7):not(:nth-child(8))){table-layout:fixed!important;margin:0!important}table:has(thead th:nth-child(7):not(:nth-child(8))) td:first-child,table:has(thead th:nth-child(7):not(:nth-child(8))) th:first-child{width:30%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(2),table:has(thead th:nth-child(7):not(:nth-child(8))) th:nth-child(2){width:18%!important;overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(3),table:has(thead th:nth-child(7):not(:nth-child(8))) th:nth-child(3),table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(4),table:has(thead th:nth-child(7):not(:nth-child(8))) th:nth-child(4),table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(5),table:has(thead th:nth-child(7):not(:nth-child(8))) th:nth-child(5),table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(6),table:has(thead th:nth-child(7):not(:nth-child(8))) th:nth-child(6){width:8%!important;text-align:center!important;padding:0.5rem 0!important}table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(7),table:has(thead th:nth-child(7):not(:nth-child(8))) th:nth-child(7){width:20%!important;text-align:center!important;padding:0.5rem 0!important;white-space:nowrap!important}table:has(thead th:nth-child(7):not(:nth-child(8))) thead tr{background:transparent!important;border-top:0!important}table:has(thead th:nth-child(7):not(:nth-child(8))) thead th{color:var(--lfm-fg)!important}table:has(thead th:nth-child(7):not(:nth-child(8))) tbody tr:has(td:first-child strong){background:var(--lfm-surface)!important}table a{text-decoration:none!important;background-image:none!important;font-weight:normal!important;padding-bottom:0!important;color:var(--lfm-success)!important;padding:0.35rem 0.5rem!important;border-radius:var(--lfm-radius)!important;transition:background-color 0.15s ease!important}table a:hover{color:var(--lfm-success-strong)!important;background-image:none!important;background-color:color-mix(in srgb, var(--lfm-success) 15%, transparent)!important}table:has(thead th:nth-child(6)) td:nth-child(2) a[href^=\"/\"]{color:var(--lfm-link)!important}table:has(thead th:nth-child(6)) td:nth-child(2) a[href^=\"/\"]:hover{color:var(--lfm-link-hover)!important}table:has(thead th:nth-child(6)) td a{border-bottom:0!important}table:has(thead th:nth-child(6):not(:nth-child(7))) td:first-child a,table:has(thead th:nth-child(7):not(:nth-child(8))) td:first-child a{color:inherit!important;font-weight:500!important;padding:0.25rem 0.4rem!important;margin:-0.25rem -0.4rem!important;border-radius:var(--lfm-radius)!important;background-image:none!important;text-decoration:none!important;transition:background-color 0.15s ease, color 0.15s ease!important}table:has(thead th:nth-child(6):not(:nth-child(7))) td:first-child a:hover,table:has(thead th:nth-child(7):not(:nth-child(8))) td:first-child a:hover{color:var(--lfm-accent)!important;background-color:var(--lfm-accent-wash)!important;background-image:none!important}table:not(:has(thead th:nth-child(6))) a{color:var(--lfm-link)!important;font-weight:400!important;text-decoration-thickness:1px!important;text-underline-offset:5px!important;text-decoration:none!important;background-image:none!important;border-bottom:0!important;padding-bottom:0!important;background-color:transparent!important;box-shadow:none!important;padding:0!important;transition:color 0.2s ease!important}table:not(:has(thead th:nth-child(6))) a:hover{color:var(--lfm-link-hover)!important;background-color:transparent!important;text-decoration-line:underline!important}.model-matrix-scroll-hint{display:none}@media (max-width: 767px){.model-matrix{container-type:inline-size;min-width:0;max-width:100%}.model-matrix [data-table-wrapper]{--page-padding: 0px}.model-matrix [data-component-part=\"scroll-area-viewport\"]{overscroll-behavior-x:contain;scroll-padding-left:calc(12rem + var(--page-padding, 0px));scroll-padding-right:var(--page-padding, 0px)}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))){min-width:48rem!important;border-collapse:separate!important}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) th,.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) td{min-width:0!important;width:auto!important;overflow:visible!important;text-overflow:clip!important;white-space:normal!important;overflow-wrap:anywhere;text-align:center!important;padding:0.5rem!important;background:var(--lfm-bg)}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) tbody td{padding:0 0.5rem!important;border-bottom:1px solid var(--lfm-border)}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) th:first-child,.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) td:first-child{position:sticky;left:var(--page-padding, 0px);z-index:20;width:12rem!important;padding:0.75rem 1rem!important;text-align:left!important;border-right:1px solid var(--lfm-border)}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) tbody td:first-child{padding:0 1rem!important}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) th:nth-child(n+2):nth-child(-n+6),.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(n+2):nth-child(-n+6){width:4rem!important}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) td:nth-child(n+2):nth-child(-n+6) a{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:0!important}.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) tbody tr:has(td:first-child strong) td{padding:0.5rem 1rem!important;background:var(--lfm-surface)}@container (max-width: 28rem){.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) th:last-child,.model-matrix table:has(thead th:nth-child(7):not(:nth-child(8))) td:last-child{padding-left:max(0.5rem, calc(28rem - 100cqw))!important}}.model-matrix-scroll-hint{display:block;color:var(--lfm-muted);font-size:var(--lfm-fs-sm)}}code:not(pre code){color:var(--lfm-link)!important;background-color:var(--lfm-accent-wash)!important;border:0!important;border-radius:var(--lfm-radius)!important;padding:0.15em 0.4em!important}.code-block-background,[class*=\"code-block\"]>div{background-color:var(--lfm-subtle)!important}.code-block,[class*=\"code-block\"].group{border-color:transparent!important}.tryit-button{background-color:var(--lfm-fg)!important;color:var(--lfm-fg-inverse)!important;font-size:var(--lfm-fs-sm)!important;font-weight:500!important;opacity:1!important;transition:background-color 0.15s ease!important}.tryit-button:hover{background-color:var(--lfm-accent)!important}.tryit-button *{color:var(--lfm-fg-inverse)!important}.tryit-button svg{background-color:var(--lfm-fg-inverse)!important}.method-pill,.method-nav-pill>span{background-color:transparent!important;box-shadow:inset 0 0 0 1px var(--lfm-border-strong)!important;color:var(--lfm-fg)!important;font-family:\"Geist Mono\", ui-monospace, SFMono-Regular, Menlo, monospace!important;font-weight:500!important;letter-spacing:0.02em!important}.method-pill{font-size:var(--lfm-fs-xs)!important}#api-playground-2-operation-page .font-mono>.border-2,[role=\"dialog\"] .font-mono>.border-2{color:var(--lfm-accent)!important;background-color:var(--lfm-accent-wash)!important;border-color:transparent!important}.code-group{border-color:transparent!important;background-color:var(--lfm-subtle)!important;padding:0!important}.code-group [data-component-part=\"code-group-tab-bar\"]{border-bottom:1px solid var(--lfm-border)!important}.code-block:not(:has([data-component-part=\"code-block-root\"].code-block-wrap)){--code-padding-right: 0px !important}.code-block:not(:has([data-component-part=\"code-block-root\"].code-block-wrap)) code>.line:first-child{padding-right:var(--fade-width, 0px)}.code-block [data-fade-overlay]{--fade-color-light: var(--lfm-subtle) !important;--fade-color-dark: var(--lfm-subtle) !important;background-color:transparent!important;border-top-right-radius:var(--lfm-radius)!important;border-bottom-right-radius:var(--lfm-radius)!important}.dark [class*=\"code-block\"]>div[class*=\"bg-codeblock\"]{background-color:var(--lfm-subtle)!important}[class*=\"code-block\"].group>div:not([class]):last-child{display:none!important}pre,pre.shiki,.shiki{background-color:var(--lfm-subtle)!important;border-radius:var(--lfm-radius)!important}pre code,.shiki code{background-color:transparent!important;border:none!important;color:var(--lfm-fg)!important}.colab-link{margin:0.5rem 0 1.5rem 0!important}.colab-link a{display:inline-block!important;background-image:none!important;border-bottom:0!important;padding-bottom:0!important}.colab-link img{display:block!important;height:24px!important;width:auto!important;margin:0!important}[role=\"tab\"][aria-selected=\"true\"]>div{color:var(--lfm-accent)!important}.nav-tabs-item>div[class*=\"bg-primary\"]{background-color:var(--lfm-accent)!important}.toc-item[data-active]>a{color:var(--lfm-fg)!important}.mdx-content div[style*=\"display\"]:has(>a[style*=\"background\"]){flex-wrap:wrap!important}.mdx-content a[style*=\"background\"]{display:inline-block!important;padding:0.3rem 0.65rem!important;border:1px solid var(--lfm-border)!important;border-radius:var(--lfm-radius)!important;background-color:transparent!important;background-image:none!important;color:var(--lfm-fg)!important;font-size:var(--lfm-fs-sm)!important;font-weight:500!important;letter-spacing:0.02em!important;line-height:1.4!important;text-decoration:none!important;transition:color 0.15s ease, background-color 0.15s ease!important}.mdx-content a[style*=\"background\"] span{color:inherit!important}.mdx-content a[style*=\"background\"]:hover{color:var(--lfm-accent)!important;background-color:var(--lfm-surface)!important}.back-button{display:inline-flex!important;align-items:center!important;gap:0.25rem!important;margin-bottom:0.75rem!important;font-size:var(--lfm-fs-sm)!important;font-weight:500!important;color:var(--lfm-muted)!important;text-decoration:none!important;background-image:none!important;border-bottom:0!important}.back-button:hover{color:var(--lfm-accent)!important;background-image:none!important}"}],"page":{"pagePath":"deployment/on-device/leap-sdk-changelog","slug":"/deployment/on-device/leap-sdk-changelog","pageMetadata":{"title":"Changelog","description":"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.","href":"/deployment/on-device/leap-sdk-changelog"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Table,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(Warning,{children:_jsxs(_components.p,{children:[`The LEAP SDK is deprecated and this page is no longer maintained. Build on llama.cpp directly instead — see `,_jsx(_components.a,{href:`/deployment/on-device/llama-cpp/migrating-from-leap-sdk`,children:`Migrating from LEAP SDK`}),`.`]})}),`\n`,_jsxs(_components.p,{children:[`Latest release: `,_jsx(_components.strong,{children:`v0.10.7`}),` (`,_jsx(_components.a,{href:`https://github.com/Liquid4All/leap-sdk/releases/tag/v0.10.7`,children:`GitHub`}),`).`]}),`\n`,_jsxs(_components.p,{children:[`This page covers user-visible changes in the LEAP SDK across releases. For per-build commit detail, see the release notes on `,_jsx(_components.a,{href:`https://github.com/Liquid4All/leap-sdk/releases`,children:_jsx(_components.code,{children:`Liquid4All/leap-sdk`})}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`0-9-x-→-0-10-x-kotlin-multiplatform-unification`,children:`0.9.x → 0.10.x: Kotlin Multiplatform unification`}),`\n`,_jsxs(_components.p,{children:[`Starting with v0.10.0, the LEAP SDK ships from a single Kotlin Multiplatform codebase. The two previously separate distributions (the Android-only `,_jsx(_components.code,{children:`ai.liquid.leap:*`}),` Maven artifacts and the iOS-only `,_jsx(_components.code,{children:`Liquid4All/leap-ios`}),` Swift package) were collapsed into one source tree that publishes to:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Swift Package Manager`}),` — `,_jsx(_components.a,{href:`https://github.com/Liquid4All/leap-sdk`,children:_jsx(_components.code,{children:`Liquid4All/leap-sdk`})}),` (new repo, for iOS / macOS consumers).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Maven Central`}),` — `,_jsx(_components.code,{children:`ai.liquid.leap:*`}),` (Android, JVM, and Kotlin/Native targets).`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The standalone `,_jsx(_components.code,{children:`Liquid4All/leap-ios`}),` repository is no longer the iOS source-of-truth. Existing 0.9.x Swift call sites (`,_jsx(_components.code,{children:`Leap.load(...)`}),`, `,_jsx(_components.code,{children:`Conversation.generateResponse(...)`}),`, etc.) keep compiling thanks to a Swift compatibility layer, but new code should adopt the unified APIs documented in the `,_jsx(_components.a,{href:`/deployment/on-device/sdk/quick-start`,children:`Quick Start`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`five-spm-products-/-four-maven-artifacts`,children:`Five SPM products / four Maven artifacts`}),`\n`,_jsx(_components.p,{children:`The unified KMP package vends a richer surface than the 0.9.x distributions:`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`SPM product`}),_jsx(_components.th,{children:`Maven artifact`}),_jsx(_components.th,{children:`Purpose`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`LeapSDK`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`ai.liquid.leap:leap-sdk`})}),_jsx(_components.td,{children:`Core inference + conversation API`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`LeapModelDownloader`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`ai.liquid.leap:leap-model-downloader`})}),_jsx(_components.td,{children:`Hosted / manifest-based model fetch`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`LeapOpenAIClient`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`ai.liquid.leap:leap-openai-client`})}),_jsx(_components.td,{children:`OpenAI-compatible cloud chat client (new in 0.10.0)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`LeapUI`})}),_jsx(_components.td,{children:_jsx(_components.code,{children:`ai.liquid.leap:leap-ui`})}),_jsx(_components.td,{children:`Voice assistant widget — Compose Multiplatform (new in 0.10.0)`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`LeapSDKMacros`})}),_jsx(_components.td,{children:_jsx(_components.em,{children:`(Swift only)`})}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`@Generatable`}),` / `,_jsx(_components.code,{children:`@Guide`}),` constrained-generation macros`]})]})]})]}),`\n`,_jsx(Heading,{level:`3`,id:`breaking-changes-for-ios-consumers`,children:`Breaking changes for iOS consumers`}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`v0.10.0 raises the minimum iOS deployment target from 15.0 to `,_jsx(_components.strong,{children:`17.0`}),` and macOS from 12.0 to `,_jsx(_components.strong,{children:`15.0`}),`. Apps targeting older OSes need to pin to `,_jsx(_components.code,{children:`0.9.x`}),` or bump their deployment target before upgrading.`]})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`SPM URL change.`}),` Point your Swift Package Manager dependency at `,_jsx(_components.code,{children:`https://github.com/Liquid4All/leap-sdk.git`}),` (not the deprecated `,_jsx(_components.code,{children:`leap-ios`}),` repo).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`CocoaPods removed.`}),` The SDK ships exclusively through SPM in v0.10.0 onward.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Toolchain bump.`}),` Xcode 16 and Swift 6.0 are required.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Swift downloader name.`}),` In current 0.10.x, Swift code instantiates `,_jsx(_components.code,{children:`ModelDownloader`}),` from the `,_jsx(_components.code,{children:`LeapModelDownloader`}),` SPM product. Android code still uses the Kotlin class `,_jsx(_components.code,{children:`ai.liquid.leap.downloader.LeapModelDownloader`}),`. See `,_jsx(_components.a,{href:`/deployment/on-device/sdk/model-loading`,children:`Model Loading`}),` for the constructor signatures.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`major-additions-since-0-9-x`,children:`Major additions since 0.9.x`}),`\n`,_jsx(_components.p,{children:`The features below were introduced in the 0.10.x line.`}),`\n`,_jsx(Heading,{level:`3`,id:`openai-compatible-cloud-client`,children:`OpenAI-compatible cloud client`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`LeapOpenAIClient`}),` / `,_jsx(_components.code,{children:`leap-openai-client`}),` is a small, dependency-light client for any OpenAI-compatible chat completions endpoint — OpenAI itself, OpenRouter, vLLM, llama-server, or your own proxy. It ships in the same package so you can route requests between an on-device LFM and a cloud model from a single app.`]}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/deployment/on-device/sdk/openai-client`,children:`OpenAI-Compatible Client`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`voice-assistant-widget`,children:`Voice assistant widget`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`LeapUI`}),` / `,_jsx(_components.code,{children:`leap-ui`}),` is a Compose Multiplatform module that ships a drop-in voice assistant widget — an animated orb, mic button, and status label — backed by a state machine that handles recording, generation, and audio playback. Stable on iOS, macOS, Android, and JVM; Wasm/Web is present in the source tree as preview.`]}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/deployment/on-device/sdk/voice-assistant`,children:`Voice Assistant Widget`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`sideloading-models-from-explicit-paths`,children:`Sideloading models from explicit paths`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`LeapDownloader.loadSimpleModel`}),` and `,_jsx(_components.code,{children:`LeapModelDownloader.loadSimpleModel`}),` load a model from explicit resource paths or URLs without going through the LEAP Model Library manifest. Useful for ADB-pushed bundles, app-bundled models, or any setup where you’ve already placed the model files on disk.`]}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/deployment/on-device/sdk/model-loading#loadsimplemodel-sideloaded-files`,children:`Model Loading — Sideloaded files`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`ios-background-downloads`,children:`iOS background downloads`}),`\n`,_jsxs(_components.p,{children:[`The iOS / macOS Swift `,_jsx(_components.code,{children:`ModelDownloader(sessionConfiguration:)`}),` initializer accepts an optional `,_jsx(_components.code,{children:`URLSessionConfiguration?`}),` so downloads can continue when the app is suspended or killed. See `,_jsx(_components.a,{href:`/deployment/on-device/sdk/model-loading#constructing-the-downloader`,children:`Model Loading → Constructing the downloader`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`autodetectcompanionfiles`,children:_jsx(_components.code,{children:`autoDetectCompanionFiles`})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`Leap.load(url:options:)`}),` on iOS gained an `,_jsx(_components.code,{children:`autoDetectCompanionFiles: Bool = true`}),` parameter that picks up companion files sitting next to the model file (e.g. multimodal projection weights).`]}),`\n`,_jsx(Heading,{level:`3`,id:`swift-ergonomics`,children:`Swift ergonomics`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Compatibility layer`}),` keeps 0.9.x call sites (`,_jsx(_components.code,{children:`Leap.load(...)`}),`, `,_jsx(_components.code,{children:`Conversation.generateResponse(...)`}),`) compiling on top of the unified KMP surface.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`onEnum(of:)`})}),` — SKIE-bridged sealed-class switching for Kotlin enums and sealed hierarchies (e.g. `,_jsx(_components.code,{children:`MessageResponse`}),`).`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`ChatMessageContent`}),` static factories`]}),` — `,_jsx(_components.code,{children:`.text(...)`}),`, `,_jsx(_components.code,{children:`.image(...)`}),`, `,_jsx(_components.code,{children:`.audio(...)`}),` helpers instead of constructor calls.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Builder-style options`}),` — `,_jsx(_components.code,{children:`LiquidInferenceEngineOptions.with(cacheOptions:)`}),`, etc.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`memory-mapped-model-loading-by-default`,children:`Memory-mapped model loading by default`}),`\n`,_jsxs(_components.p,{children:[`Starting in `,_jsx(_components.strong,{children:`v0.10.4`}),` and on by default through the current release, the inference engine loads model weights via `,_jsx(_components.code,{children:`mmap`}),` (`,_jsx(_components.code,{children:`use_mmap=true`}),`). It’s the default behavior for every loaded model. On mobile this is the most user-visible runtime change in the 0.10.x line. A public opt-out arrived in `,_jsx(_components.strong,{children:`v0.10.5`}),` as `,_jsx(_components.code,{children:`ModelLoadingOptions.useMmap: Boolean?`}),` (Kotlin) / `,_jsx(_components.code,{children:`LiquidInferenceEngineOptions(useMmap:)`}),` (Swift) — leave it `,_jsx(_components.code,{children:`null`}),`/`,_jsx(_components.code,{children:`nil`}),` to keep the default, or set `,_jsx(_components.code,{children:`false`}),` for filesystems where `,_jsx(_components.code,{children:`mmap`}),` misbehaves (some Android scoped-storage paths, certain network mounts).`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`What changed.`}),` Previously the engine `,_jsx(_components.code,{children:`read(2)`}),`-ed the entire model file into a heap-allocated buffer before running prefill. Now it memory-maps the file: the kernel maps the on-disk weights into the process’s virtual address space and loads pages lazily as they’re accessed.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Performance implications on mobile:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Lower private RSS.`}),` mmap’d weights are file-backed pages, not “anonymous private” RSS. iOS’s jetsam and Android’s low-memory killer both score apps primarily by anonymous RSS, so a 1.2B-Q4 model that previously counted as ~700 MB of dirty heap now shows as backing pages the OS may evict for free. Foreground apps are significantly less likely to be terminated under memory pressure.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Faster cold load.`}),` The constructor returns as soon as the file is mapped — typically tens of milliseconds — instead of waiting for the entire model to be read into RAM. The first inference pays the page-in cost incrementally as the engine touches weights.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Faster warm reloads.`}),` After the first load, the kernel’s page cache holds the model’s hot pages. Re-creating a runner on the same model (e.g. after a background termination and relaunch within the same boot) is near-instant — pages stream from the page cache, not disk.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Multi-model sharing.`}),` Two processes (or two runners in one process) loading the same model file share physical pages via the page cache, with no extra RAM cost.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Graceful memory pressure.`}),` When the OS needs RAM for the foreground UI or another app, it can drop read-only model pages without writing them anywhere (they’re backed by the file). The next access re-pages them in. With anonymous heap buffers, the kernel had to choose between swapping (slow) or killing the app (worse).`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Trade-offs:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`First-token latency on cold pages.`}),` The first generation against a freshly-mapped model triggers page faults as the engine walks the weights. This adds disk-I/O latency to TTFT on the first call after process start. The KV cache reuse documented `,_jsx(_components.a,{href:`#kv-cache-reuse-across-generations`,children:`above`}),` compounds well here: cached prefixes skip both prefill compute `,_jsx(_components.em,{children:`and`}),` the page-fault cost for weights touched during prefill.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Storage type matters.`}),` On devices with slow eMMC / external SD storage, lazy page-in can be noticeably slower than the old eager-read flow that loaded the whole file once. Internal flash on every shipped iOS device and any modern Android device is fast enough that this isn’t visible in practice.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Opt-out available since v0.10.5.`}),` Pass `,_jsx(_components.code,{children:`useMmap = false`}),` on `,_jsx(_components.code,{children:`ModelLoadingOptions`}),` (Kotlin) or `,_jsx(_components.code,{children:`LiquidInferenceEngineOptions(useMmap: false)`}),` (Swift) to force the legacy full-read loader. Use only when `,_jsx(_components.code,{children:`mmap`}),` misbehaves on the target filesystem; the default of `,_jsx(_components.code,{children:`null`}),`/`,_jsx(_components.code,{children:`nil`}),` keeps the engine default.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`This change shipped via the inference-engine vendor pin bumped in v0.10.4 (`,_jsx(_components.code,{children:`v26.02.1-79-ge5f65988dc`}),`). The default has stayed on through every subsequent pin cascade.`]}),`\n`,_jsx(Heading,{level:`3`,id:`kv-cache-reuse-across-generations`,children:`KV cache reuse across generations`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`CacheOptions`}),` (new in v0.10.4, ergonomic Swift surface in v0.10.4.3) lets the engine persist KV-cache data between `,_jsx(_components.code,{children:`generateResponse`}),` calls so requests that share a prompt prefix skip the prefill work for the shared tokens.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Disabled by default.`}),` `,_jsx(_components.code,{children:`cacheOptions`}),` is `,_jsx(_components.code,{children:`nil`}),` (Swift) / `,_jsx(_components.code,{children:`null`}),` (Kotlin) until you explicitly pass `,_jsx(_components.code,{children:`LiquidCacheOptions.enabled(path:)`}),` / `,_jsx(_components.code,{children:`ModelLoadingOptions.cacheOptions(path:)`}),`. Apps that don’t opt in see no prefix reuse and no on-disk cache directory created — same behavior as 0.9.x and pre-0.10.4 builds.`]})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Why it matters.`}),` Transformer inference has two phases: `,_jsx(_components.strong,{children:`prefill`}),` (compute keys and values for every prompt token) and `,_jsx(_components.strong,{children:`decode`}),` (generate one new token at a time, reusing those K/V vectors). On mobile, prefill dominates time-to-first-token for any prompt longer than a few hundred tokens. With `,_jsx(_components.code,{children:`CacheOptions`}),` enabled, a previously seen prefix is read from disk instead of recomputed — TTFT can drop from seconds to under a hundred milliseconds on cache hits. Per-token decode cost is unchanged.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`When it speeds things up.`}),` Anywhere the same tokens appear at the start of many requests:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Multi-turn chat with a long system prompt.`}),` Every turn reuses the system prompt and earlier turns.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`RAG / retrieval-augmented generation.`}),` Many queries share the retrieved-document preamble.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Few-shot prompting.`}),` A fixed set of examples precedes every request.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Agent loops.`}),` Tool definitions, role instructions, and task scaffold are stable across iterations.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Voice assistant continuations.`}),` Conversation history grows; everything before the latest user turn is cacheable.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The cache is a bounded LRU — the engine caps cache size and evicts the least-recently-used entries automatically; you do not need to manage the directory yourself. See `,_jsx(_components.a,{href:`/deployment/on-device/sdk/model-loading#kv-cache-reuse`,children:`Model Loading → KV cache reuse`}),` for the per-platform configuration.`]}),`\n`,_jsx(_components.p,{children:`Minimal config:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`9`,language:`swift`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`swift`,children:_jsxs(_components.code,{language:`swift`,numberOfLines:`9`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:`// iOS / macOS (v0.10.4.3+)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`let`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` cacheDir `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` FileManager.default.`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`urls`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`for`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`: .cachesDirectory, `}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`in`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`: .userDomainMask)[`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`0`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` .`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`appendingPathComponent`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`\"leap-kv-cache\"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`let`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` options `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` LiquidInferenceEngineManifestOptions`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` cacheOptions`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`: .`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`enabled`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`path`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`: cacheDir.path),`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:` contextSize`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`: `}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`4096`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`let`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` runner `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` try`}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:` await`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` Leap.`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`load`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(`}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`url`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`: bundleURL, `}),_jsx(_components.span,{style:{color:`#005CC5`,\"--shiki-dark\":`#79B8FF`},children:`options`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`: options)`})]}),`\n`]})})}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`kotlin`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`kotlin`,children:_jsxs(_components.code,{language:`kotlin`,numberOfLines:`10`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6A737D`,\"--shiki-dark\":`#6A737D`},children:`// Android / JVM / KMP (v0.10.5+)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`val`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` cacheDir `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` context.cacheDir.`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`resolve`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:`\"leap-kv-cache\"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`).`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`apply`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` { `}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`mkdirs`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`() }`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`val`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` runner `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` downloader.`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`loadModel`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` modelName `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"LFM2-1.2B\"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` quantizationType `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#032F62`,\"--shiki-dark\":`#9ECBFF`},children:` \"Q5_K_M\"`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` options `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:` ModelLoadingOptions`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`().`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`apply`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` cacheOptions `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` ModelLoadingOptions.`}),_jsx(_components.span,{style:{color:`#6F42C1`,\"--shiki-dark\":`#B392F0`},children:`cacheOptions`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`(path `}),_jsx(_components.span,{style:{color:`#D73A49`,\"--shiki-dark\":`#F97583`},children:`=`}),_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` cacheDir.absolutePath)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#24292E`,\"--shiki-dark\":`#E1E4E8`},children:`)`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`per-release-notes`,children:`Per-release notes`}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-7-—-2026-05-18`,children:`v0.10.7 — 2026-05-18`}),`\n`,_jsxs(_components.p,{children:[`KMP target completion for `,_jsx(_components.code,{children:`leap-openai-client`}),` plus a repo-wide bytecode-hardening pass. iOS / macOS Swift surface is unchanged from v0.10.6 — this is a Kotlin/JVM ergonomics release for non-Apple consumers.`]}),`\n`,_jsxs(_components.p,{children:[_jsxs(_components.strong,{children:[`New targets on `,_jsx(_components.code,{children:`leap-openai-client`})]}),` (`,_jsx(_components.a,{href:`https://github.com/Liquid4All/leap-android-sdk/pull/256`,children:`PR #256`}),`):`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`jvm`})}),` (Ktor CIO engine) — Maven Central now publishes `,_jsx(_components.code,{children:`ai.liquid.leap:leap-openai-client-jvm:0.10.7`}),`. Pure-JVM desktop / server apps can route OpenAI-compatible chat completions without dragging in Android or KMP targets. (The 0.10.0 — 0.10.6 SPM cascade only shipped Android + Apple + Linux/MinGW K/N + wasmJs metadata; the JVM slice was absent.)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`wasmJs`})}),` (Ktor Js engine) — browser-side chat-completions client matching what `,_jsx(_components.code,{children:`leap-sdk`}),` already targets.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`The Apple slice (`,_jsx(_components.code,{children:`LeapOpenAIClient.xcframework`}),`) ships unchanged — same SSE-stream surface, same `,_jsx(_components.code,{children:`OpenAiClientConfig`}),`, same OpenRouter extra-headers support. SKIE is still not applied to this module in v0.10.7, so the Kotlin/Native exports remain the same as v0.10.6: `,_jsx(_components.code,{children:`Flow\u003cChatCompletionEvent>`}),` is not bridged to Swift `,_jsx(_components.code,{children:`AsyncSequence`}),`, and `,_jsx(_components.code,{children:`onEnum(of:)`}),` is not generated for `,_jsx(_components.code,{children:`ChatCompletionEvent`}),`. `,_jsxs(_components.strong,{children:[`The next release will enable SKIE on `,_jsx(_components.code,{children:`leap-sdk-openai-client`})]}),`, bringing `,_jsx(_components.code,{children:`for try await`}),` over the stream, exhaustive `,_jsx(_components.code,{children:`onEnum(of:)`}),` switching, and SKIE-bundled Swift convenience inits — see the `,_jsx(_components.a,{href:`/deployment/on-device/sdk/openai-client`,children:`OpenAI client page`}),` for the current pinning guidance.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Bytecode hardening:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`The `,_jsx(_components.code,{children:`leap-sdk-jvm`}),`, `,_jsx(_components.code,{children:`leap-openai-client-jvm`}),`, `,_jsx(_components.code,{children:`leap-ui-jvm`}),`, and `,_jsx(_components.code,{children:`leap-ui-android`}),` artifacts had been silently shipping Java 17 / Java 21 bytecode against the project’s stated JVM-target-11 stance. All ten published JVM / Android slices now consistently emit class-file major version `,_jsx(_components.code,{children:`0x37`}),` (Java 11). Consumers running on JDK 11 — particularly long-running services and JDK-11-pinned Android Gradle builds — are no longer at risk of `,_jsx(_components.code,{children:`UnsupportedClassVersionError`}),`.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Internal: KMP build centralization`}),` (no consumer-visible API change):`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Root-level `,_jsx(_components.code,{children:`subprojects { tasks.withType\u003cKotlinCompile>().configureEach { compilerOptions { jvmTarget.set(JvmTarget.JVM_11) } } }`}),` replaces 17 per-site `,_jsx(_components.code,{children:`JVM_11`}),` pins.`]}),`\n`,_jsxs(_components.li,{children:[`Karma + headless Chrome runner for `,_jsx(_components.code,{children:`wasmJs`}),` targets centralized into the same `,_jsx(_components.code,{children:`subprojects {}`}),` block — replaces 3 per-site copies. Future modules pick up both patterns automatically.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Test coverage:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`OpenAiClientTest`}),`’s seven SSE-stream + auth-header + error-event + malformed-chunk cases were promoted from `,_jsx(_components.code,{children:`androidHostTest`}),` to `,_jsx(_components.code,{children:`commonTest`}),`. They now also run on `,_jsx(_components.code,{children:`jvmTest`}),`, `,_jsx(_components.code,{children:`macosArm64Test`}),`, `,_jsx(_components.code,{children:`iosSimulatorArm64Test`}),`, `,_jsx(_components.code,{children:`linuxX64Test`}),`, `,_jsx(_components.code,{children:`mingwX64Test`}),`, and `,_jsx(_components.code,{children:`wasmJsTest`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`iOS surface (unchanged from v0.10.6):`})}),`\n`,_jsxs(_components.p,{children:[`The four XCFrameworks (`,_jsx(_components.code,{children:`LeapSDK`}),`, `,_jsx(_components.code,{children:`LeapModelDownloader`}),`, `,_jsx(_components.code,{children:`LeapOpenAIClient`}),`, `,_jsx(_components.code,{children:`LeapUi`}),`) ship the same Swift APIs as v0.10.6. The v0.10.6 ObjC class rename to `,_jsx(_components.code,{children:`ModelDownloader`}),`, the dual-import guard, the dynamic `,_jsx(_components.code,{children:`LeapModelDownloader`}),` framework, and the `,_jsx(_components.code,{children:`LeapDownloaderConfig()`}),` parameterless init all remain in place.`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-6-—-2026-05-12`,children:`v0.10.6 — 2026-05-12`}),`\n`,_jsxs(_components.p,{children:[`iOS `,_jsx(_components.code,{children:`ModelDownloader`}),` (the Swift class formerly known as `,_jsx(_components.code,{children:`LeapModelDownloader`}),` — see the rename note below) reaches parity with the cross-platform `,_jsx(_components.code,{children:`LeapDownloader`}),`. Callers no longer need to pair the two classes to download and load a model on Apple platforms — every entry point routes file transfer through `,_jsx(_components.code,{children:`URLSession`}),` and then hands off to the loader.`]}),`\n`,_jsx(_components.p,{children:_jsxs(_components.strong,{children:[`New iOS API on `,_jsx(_components.code,{children:`ModelDownloader`}),`:`]})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`loadModel(modelName:, quantizationType:, options:, generationTimeParameters:, forceDownload:, downloadProgress:)`})}),` — downloads (when needed) and loads in one call. The transfer registers in `,_jsx(_components.code,{children:`queryStatus`}),`, is cancellable via `,_jsx(_components.code,{children:`requestStopDownload`}),`, and continues across backgrounding when constructed with `,_jsx(_components.code,{children:`sessionConfiguration: .backgroundSessionConfiguration(withIdentifier:)`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`loadModel(manifestUrl:, options:, generationTimeParameters:, forceDownload:, downloadProgress:)`})}),` — same flow keyed by a manifest URL.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`loadSimpleModel(model: ModelSource, options:, generationTimeParameters:, downloadProgress:)`})}),` — sideload from explicit paths or URLs; HTTPS sources stream through `,_jsx(_components.code,{children:`URLSession`}),`, local paths pass straight through.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`forceDownload: Bool = false`})}),` on all three load methods. Resolves the manifest first, then deletes the local cache, then re-downloads — a registry failure on resolve leaves the previously-working cached copy intact.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Resource-lookup helpers`}),` that previously lived only on the cross-platform `,_jsx(_components.code,{children:`LeapDownloader`}),`: `,_jsx(_components.code,{children:`getModelResourceFolder(...)`}),`, `,_jsx(_components.code,{children:`getCachedManifest(...)`}),`, `,_jsx(_components.code,{children:`getCachedFilePath(...)`}),`, `,_jsx(_components.code,{children:`resolve(...)`}),`, `,_jsx(_components.code,{children:`deleteModelFile(...)`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`requestDownloadModel(manifestUrl:, forceDownload:)`})}),` overload for symmetry with `,_jsx(_components.code,{children:`removeModel(manifestUrl:)`}),` / `,_jsx(_components.code,{children:`queryStatus(manifestUrl:)`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Breaking changes (Swift):`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Class renamed: `,_jsx(_components.code,{children:`LeapModelDownloader`}),` → `,_jsx(_components.code,{children:`ModelDownloader`})]}),` on iOS / macOS. The Kotlin class still lives in `,_jsx(_components.code,{children:`ai.liquid.leap.downloader.LeapModelDownloader`}),` and Android consumers are unaffected; a `,_jsx(_components.code,{children:`@ObjCName(swiftName = \"ModelDownloader\")`}),` annotation gives the Swift export an unambiguous name distinct from the framework module’s own `,_jsx(_components.code,{children:`LeapModelDownloader`}),` name. Update Swift call sites:`,`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`diff`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light github-dark`,style:{backgroundColor:`#fff`,\"--shiki-dark-bg\":`#24292e`,color:`#24292e`,\"--shiki-dark\":`#e1e4e8`},language:`diff`,children:_jsxs(_components.code,{language:`diff`,numberOfLines:`2`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#B31D28`,\"--shiki-dark\":`#FDAEB7`},children:`- let downloader = LeapModelDownloader() // was uninstantiable from Swift in 0.10.5 due to the class-vs-module name collision`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#22863A`,\"--shiki-dark\":`#85E89D`},children:`+ let downloader = ModelDownloader()`})}),`\n`]})})}),`\n`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Parameter labels renamed across the iOS `,_jsx(_components.code,{children:`ModelDownloader`}),` surface`]}),` — `,_jsx(_components.code,{children:`model:`}),` / `,_jsx(_components.code,{children:`quantization:`}),` → `,_jsx(_components.code,{children:`modelName:`}),` / `,_jsx(_components.code,{children:`quantizationType:`}),` on every method that already existed: `,_jsx(_components.code,{children:`downloadModel(...)`}),`, `,_jsx(_components.code,{children:`requestDownloadModel(...)`}),`, `,_jsx(_components.code,{children:`requestStopDownload(...)`}),`, `,_jsx(_components.code,{children:`queryStatus(...)`}),`, `,_jsx(_components.code,{children:`removeModel(...)`}),`, `,_jsx(_components.code,{children:`getModelSize(...)`}),`. Every loader now uses the same labels across Swift and Kotlin — `,_jsx(_components.code,{children:`ModelDownloader`}),` (iOS, macOS), `,_jsx(_components.code,{children:`LeapModelDownloader`}),` (Android), and `,_jsx(_components.code,{children:`LeapDownloader`}),` (cross-platform) all share `,_jsx(_components.code,{children:`modelName:`}),` / `,_jsx(_components.code,{children:`quantizationType:`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`LeapModelDownloader`}),` SPM library product is now single-target.`]}),` It no longer bundles the `,_jsx(_components.code,{children:`LeapSDK`}),` target. Apps depending on this product must drop any direct `,_jsx(_components.code,{children:`LeapSDK`}),` SPM dependency from the same target — `,_jsx(_components.code,{children:`import LeapModelDownloader`}),` re-exports every LeapSDK Kotlin type (`,_jsx(_components.code,{children:`Conversation`}),`, `,_jsx(_components.code,{children:`ModelRunner`}),`, `,_jsx(_components.code,{children:`ChatMessage`}),`, `,_jsx(_components.code,{children:`Leap`}),`, the convenience extensions, …). Keeping both library products on the same target double-bundles the inference engine dylibs and triggers a build-time `,_jsx(_components.code,{children:`#error`}),` from the LMD umbrella header (see “dual-import guard” below); the `,_jsx(_components.code,{children:`LeapUI`}),` library product still bundles `,_jsx(_components.code,{children:`LeapSDK`}),` because LeapUI does not re-emit those types in its ObjC binding.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`LeapModelDownloader.xcframework`}),` is now a dynamic framework.`]}),` It was a static archive in 0.10.5. SPM applies Embed \u0026 Sign automatically; manual integrators must add the framework with “Embed \u0026 Sign” instead of “Do Not Embed”. The shipped XCFramework now also bundles the inference engine dylibs (`,_jsx(_components.code,{children:`libinference_engine.dylib`}),`, `,_jsx(_components.code,{children:`libinference_engine_llamacpp_backend.dylib`}),`, `,_jsx(_components.code,{children:`libie_zip.dylib`}),`) under `,_jsx(_components.code,{children:`Frameworks/`}),` with an `,_jsx(_components.code,{children:`@loader_path/Frameworks`}),` LC_RPATH — consumers using LMD on its own no longer need `,_jsx(_components.code,{children:`LeapSDK.framework/Frameworks`}),` on their search path.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Dual-import build-time guard.`}),` LMD’s umbrella header carries a `,_jsx(_components.code,{children:`__has_include(\u003cLeapSDK/LeapSDK.h>) \u0026\u0026 !defined(LEAP_DUAL_IMPORT_ALLOW)`}),` check that fires `,_jsx(_components.code,{children:`#error`}),` at the consumer’s preprocessing time when both `,_jsx(_components.code,{children:`LeapSDK`}),` and `,_jsx(_components.code,{children:`LeapModelDownloader`}),` frameworks are reachable in the same target. To opt out for legitimate combinations (e.g. transitive linkage via `,_jsx(_components.code,{children:`LeapUI`}),`), add `,_jsx(_components.code,{children:`LEAP_DUAL_IMPORT_ALLOW=1`}),` to `,_jsx(_components.code,{children:`OTHER_CFLAGS`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`New Swift conveniences:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`ModelDownloader()`})}),`, `,_jsx(_components.strong,{children:_jsx(_components.code,{children:`ModelDownloader(sessionConfiguration:)`})}),`, `,_jsx(_components.strong,{children:_jsx(_components.code,{children:`ModelDownloader(config:)`})}),` — Kotlin/Native ObjC export strips default-argument metadata, so 0.10.5 forced Swift callers to pass every parameter (and `,_jsx(_components.code,{children:`LeapDownloaderConfig`}),` has seven). These new SKIE-bundled convenience inits restore the parameterless / single-arg forms.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`LeapDownloaderConfig()`})}),` parameterless convenience init mirroring the Kotlin defaults (`,_jsx(_components.code,{children:`saveDir = \"leap_models\"`}),`, `,_jsx(_components.code,{children:`validateSha256 = true`}),`, etc.). Same rationale — `,_jsx(_components.code,{children:`LeapDownloaderConfig`}),` is a Kotlin `,_jsx(_components.code,{children:`data class`}),` with seven defaulted fields that the ObjC export couldn’t carry through.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Behavior changes:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`requestDownloadModel(forceDownload: false)`})}),` now short-circuits when a cached manifest already exists `,_jsx(_components.em,{children:`and`}),` every resource referenced by that manifest is present on disk — matches both the Android downloader’s idempotent-call semantics and what `,_jsx(_components.code,{children:`queryStatus(...)`}),` already reports. Earlier 0.10.5 builds would short-circuit on the manifest alone, leaving the caller stuck if any resource file had been removed. Pass `,_jsx(_components.code,{children:`forceDownload: true`}),` to re-download on top of a cache.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Cached-file lookup`}),` uses Ktor URL parsing instead of substring slicing, so URLs with fragments or query strings now produce the same filename the loader expects (`,_jsx(_components.code,{children:`getCachedFilePath`}),` was previously brittle for those shapes).`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Fixes:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`getAvailableDiskSpace()`})}),` previously returned `,_jsx(_components.code,{children:`null`}),` on every Apple platform because the internal `,_jsx(_components.code,{children:`NSFileManager.attributesOfFileSystem(forPath:)[.systemFreeSize]`}),` extraction cast through `,_jsx(_components.code,{children:`as? Long`}),` (Kotlin) which never matches the bridged `,_jsx(_components.code,{children:`NSNumber`}),`. Now goes through `,_jsx(_components.code,{children:`NSNumber.longLongValue`}),` and reports the real free-space figure.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Other changes:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Options on the new load methods take `,_jsx(_components.code,{children:`LiquidInferenceEngineManifestOptions?`}),` (the Swift-friendly type already used by `,_jsx(_components.code,{children:`Leap.load`}),`), with `,_jsx(_components.code,{children:`toModelLoadingOptions()`}),` / `,_jsx(_components.code,{children:`toGenerationTimeParameters()`}),` conversion at the boundary — no separate KMP options class needed from Swift.`]}),`\n`,_jsxs(_components.li,{children:[`Internal: the iOS class uses `,_jsx(_components.code,{children:`kotlin.experimental.ExperimentalObjCName`}),` (stable in our Kotlin 2.3.20 baseline but still formally experimental).`]}),`\n`,_jsx(_components.li,{children:`No public-API changes for Android or non-Apple Kotlin/Native targets.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-5-—-2026-05-11`,children:`v0.10.5 — 2026-05-11`}),`\n`,_jsxs(_components.p,{children:[`Headline additions: Android Leap Model Service for cross-app model sharing, the `,_jsx(_components.code,{children:`useMmap`}),` knob on `,_jsx(_components.code,{children:`ModelLoadingOptions`}),`, and a parameter-name cleanup on `,_jsx(_components.code,{children:`LeapDownloader.loadModel`}),` so it matches `,_jsx(_components.code,{children:`LeapModelDownloader.loadModel`}),`.`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Breaking changes (Kotlin):`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`ModelLoadingOptions.cacheDir: String?`}),` → `,_jsx(_components.code,{children:`cacheOptions: EngineOptions.CacheOptions?`})]}),` — KV cache configuration moves to a bounded-LRU `,_jsx(_components.code,{children:`CacheOptions`}),` value with explicit `,_jsx(_components.code,{children:`enabled`}),` master switch, per-tier caps (`,_jsx(_components.code,{children:`maxEntriesDisk`}),`, `,_jsx(_components.code,{children:`maxEntriesMemory`}),`, `,_jsx(_components.code,{children:`maxBytesMemory`}),`), and optional `,_jsx(_components.code,{children:`diskDisabled = true`}),` for memory-only mode. Migrate via the `,_jsx(_components.code,{children:`ModelLoadingOptions.cacheOptions(path = ...)`}),` factory (preserves the historical 40-entry disk budget and sets `,_jsx(_components.code,{children:`enabled = true`}),`). Constructing a raw `,_jsx(_components.code,{children:`CacheOptions`}),` requires `,_jsx(_components.code,{children:`enabled = true`}),` to enable the cache — a positive `,_jsx(_components.code,{children:`maxEntries`}),` alone is no longer sufficient.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`LeapDownloader.loadModel(modelName, quantizationSlug, modelLoadingOptions, …)`}),` → `,_jsx(_components.code,{children:`loadModel(modelName, quantizationType, options, …)`})]}),` — parameter renames bring `,_jsx(_components.code,{children:`LeapDownloader`}),` in line with `,_jsx(_components.code,{children:`LeapModelDownloader`}),`. The same rename applies to `,_jsx(_components.code,{children:`loadSimpleModel(model, modelLoadingOptions, …)`}),` → `,_jsx(_components.code,{children:`loadSimpleModel(model, options, …)`}),` and `,_jsx(_components.code,{children:`loadModelFromManifestUrl(…)`}),`. Swift sites that called `,_jsx(_components.code,{children:`downloader.loadModel(modelName:, quantizationSlug:, modelLoadingOptions:)`}),` need to swap to `,_jsx(_components.code,{children:`quantizationType:`}),` / `,_jsx(_components.code,{children:`options:`}),` after upgrading.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`progress`}),` is now nullable`]}),` (`,_jsx(_components.code,{children:`progress: ((ProgressData) -> Unit)? = null`}),`) — pass `,_jsx(_components.code,{children:`null`}),` to opt out (was an empty-lambda default).`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`New features:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.code,{children:`ModelLoadingOptions.useMmap: Boolean? = null`})}),` — exposes the engine’s `,_jsx(_components.code,{children:`use_mmap`}),` toggle to Kotlin/Swift callers. `,_jsx(_components.code,{children:`null`}),` (default) defers to the engine default of `,_jsx(_components.code,{children:`true`}),`. Set `,_jsx(_components.code,{children:`false`}),` only on filesystems where `,_jsx(_components.code,{children:`mmap`}),` misbehaves (some Android scoped-storage paths, certain network mounts). On Swift, `,_jsx(_components.code,{children:`LiquidInferenceEngineOptions`}),` gained a matching `,_jsx(_components.code,{children:`.with(useMmap:)`}),` builder. Previously mmap could not be disabled from the SDK.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Leap Model Service (Android)`}),` — `,_jsx(_components.code,{children:`leap-model-service`}),` is a new optional Android service that hosts loaded models in its own process and lets multiple client apps share them. Apps using `,_jsx(_components.code,{children:`LeapModelDownloader.loadModel(...)`}),` route through the service transparently when it’s installed on the device; otherwise they fall back to in-process loading. Per-UID session quotas, persistent foreground notification, disk-backed KV cache reuse across cold starts, and AIDL-routed `,_jsx(_components.code,{children:`registerFunction(s)`}),`. Pass `,_jsx(_components.code,{children:`forceLocal = true`}),` on `,_jsx(_components.code,{children:`LeapModelDownloader.loadModel(...)`}),` to bypass the service for testing. See `,_jsx(_components.a,{href:`/deployment/on-device/sdk/model-loading`,children:`Model Loading`}),` for the routing model.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Service-side load progress`}),` — when routing through the model service, `,_jsx(_components.code,{children:`LeapModelDownloader.loadModel`}),`’s `,_jsx(_components.code,{children:`progress`}),` callback now fires for service-side downloads too (was previously local-path-only).`]}),`\n`]}),`\n`,_jsx(_components.p,{children:_jsx(_components.strong,{children:`Fixes / refresh:`})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Apple `,_jsx(_components.code,{children:`LeapModelDownloader`}),` internal slot names switched from `,_jsx(_components.code,{children:`quantizationSlug`}),` → `,_jsx(_components.code,{children:`quantizationType`}),` for consistency. Public Swift label names (`,_jsx(_components.code,{children:`model:`}),` / `,_jsx(_components.code,{children:`quantization:`}),`) are unchanged.`]}),`\n`,_jsxs(_components.li,{children:[`Vendor `,_jsx(_components.code,{children:`liquid.h`}),` header refresh for Linux/MinGW K/N targets.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-4-5-—-2026-05-08`,children:`v0.10.4.5 — 2026-05-08`}),`\n`,_jsx(_components.p,{children:`Engine ABI fix release. SPM consumers should bump to this version.`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Engine pin advanced to `,_jsx(_components.code,{children:`v26.02.1-146-g777faf0dbb`}),` — fixes a K/N + Linux `,_jsx(_components.code,{children:`free(): invalid pointer`}),` SIGABRT in `,_jsx(_components.code,{children:`liquid_string_destroy`}),` (the FFI helper was freeing the wrong pointer slot).`]}),`\n`,_jsx(_components.li,{children:`Linux runtime smoke test now asserts the engine reports failure on a missing model path, guarding against silent-success regressions.`}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`NativeLibLoader`}),` cleanup: stdout warnings moved to `,_jsx(_components.code,{children:`System.err`}),`; loader stays kotlin-stdlib-only.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-4-4-—-2026-05-07`,children:`v0.10.4.4 — 2026-05-07`}),`\n`,_jsxs(_components.p,{children:[`K/N link-time `,_jsx(_components.code,{children:`--allow-shlib-undefined`}),` fix for Linux consumers. No API changes.`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-4-3-—-2026-05-07`,children:`v0.10.4.3 — 2026-05-07`}),`\n`,_jsxs(_components.p,{children:[`iOS/macOS Swift convenience surface for `,_jsx(_components.code,{children:`cacheOptions`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`LiquidInferenceEngineManifestOptions(cacheOptions: ..., contextSize: 4096)`}),` now accepts native Swift types (previously the convenience init dropped `,_jsx(_components.code,{children:`cacheOptions`}),` and forced consumers to the verbose Obj-C designated init).`]}),`\n`,_jsxs(_components.li,{children:[`New `,_jsx(_components.code,{children:`with(cacheOptions:)`}),` builders on `,_jsx(_components.code,{children:`LiquidInferenceEngineOptions`}),` and `,_jsx(_components.code,{children:`LiquidInferenceEngineManifestOptions`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`New `,_jsx(_components.code,{children:`LiquidCacheOptions.enabled(path:)`}),` static factory — Swift analog of `,_jsx(_components.code,{children:`ModelLoadingOptions.cacheOptions(path:)`}),`.`]}),`\n`]}),`\n`,_jsx(_components.p,{children:`(v0.10.4.2 was staged to Sonatype but never released; superseded by 0.10.4.3.)`}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-4-1-—-2026-05-07`,children:`v0.10.4.1 — 2026-05-07`}),`\n`,_jsxs(_components.p,{children:[`Vendor pin refresh — bumps the inference engine to `,_jsx(_components.code,{children:`v26.02.1-142-gb4aa080538`}),`. Adds Strategy B chain-prefix replay for cold/warm bit-determinism and generalizes the Android backend native loader to Linux and Windows desktop. No public API changes.`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-4-—-2026-05-06`,children:`v0.10.4 — 2026-05-06`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[`Bounded-LRU `,_jsx(_components.code,{children:`CacheOptions`}),` API`]}),` across JVM, Android, Kotlin/Native, Apple, and wasmJs.`]}),`\n`,_jsxs(_components.li,{children:[_jsxs(_components.strong,{children:[_jsx(_components.code,{children:`use_mmap=true`}),` is now the engine default`]}),` (via vendored IE pin `,_jsx(_components.code,{children:`v26.02.1-79+`}),`). Model weights are memory-mapped instead of `,_jsx(_components.code,{children:`read(2)`}),`-ed into a heap buffer. See `,_jsx(_components.a,{href:`#memory-mapped-model-loading-by-default`,children:`Memory-mapped model loading by default`}),` above for the mobile performance impact.`]}),`\n`,_jsxs(_components.li,{children:[`K/N Linux link fix (`,_jsx(_components.code,{children:`--allow-shlib-undefined`}),` for `,_jsx(_components.code,{children:`libinference_engine.so`}),` against modern glibc).`]}),`\n`,_jsxs(_components.li,{children:[`Dynamic vendor pipeline + `,_jsx(_components.code,{children:`DT_NEEDED`}),`-based shipped-libs verify; `,_jsx(_components.code,{children:`inference_engine`}),` RUNPATH=`,_jsx(_components.code,{children:`$ORIGIN`}),` cascade for Linux/Windows shared vendor libs.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`NativeLibLoader`}),` cross-platform load fixes (resource extraction + Windows pre-load topo-retry).`]}),`\n`,_jsx(_components.li,{children:`Three release-gate smokes (Linux K/N, Apple SwiftPM consumer, Windows JVM) wired into CI.`}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-1-—-2026-04-29`,children:`v0.10.1 — 2026-04-29`}),`\n`,_jsx(_components.p,{children:`Additive fix release for Linux/MinGW Kotlin/Native consumers. Apple/SPM consumers see no API or behavior changes vs v0.10.0.`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`leap-sdk`}),` Linux/MinGW K/N artifacts on Maven Central now publish a `,_jsx(_components.code,{children:`-natives.zip`}),` classifier containing the runtime `,_jsx(_components.code,{children:`.so`}),`/`,_jsx(_components.code,{children:`.dll`}),` libraries.`]}),`\n`,_jsxs(_components.li,{children:[`New `,_jsx(_components.code,{children:`ai.liquid.leap.nativelibs`}),` Gradle plugin auto-wires the natives ZIP into consumer K/N executables.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`leap-openai-client`}),` now publishes Linux/MinGW K/N klibs.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`3`,id:`v0-10-0-—-2026-04-28`,children:`v0.10.0 — 2026-04-28`}),`\n`,_jsxs(_components.p,{children:[`Initial Kotlin Multiplatform unification release. See `,_jsx(_components.a,{href:`#0-9-x-0-10-x-kotlin-multiplatform-unification`,children:`the 0.9.x → 0.10.x section above`}),` for the full migration story.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":{"theme":{"light":"github-light","dark":"github-dark"}},"config":{},"pageMetadata":{"title":"Changelog","description":"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.","href":"/deployment/on-device/leap-sdk-changelog"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"0.9.x → 0.10.x: Kotlin Multiplatform unification","slug":"0-9-x-→-0-10-x-kotlin-multiplatform-unification","depth":2,"children":[{"title":"Five SPM products / four Maven artifacts","slug":"five-spm-products-/-four-maven-artifacts","depth":3,"children":[]},{"title":"Breaking changes for iOS consumers","slug":"breaking-changes-for-ios-consumers","depth":3,"children":[]}]},{"title":"Major additions since 0.9.x","slug":"major-additions-since-0-9-x","depth":2,"children":[{"title":"OpenAI-compatible cloud client","slug":"openai-compatible-cloud-client","depth":3,"children":[]},{"title":"Voice assistant widget","slug":"voice-assistant-widget","depth":3,"children":[]},{"title":"Sideloading models from explicit paths","slug":"sideloading-models-from-explicit-paths","depth":3,"children":[]},{"title":"iOS background downloads","slug":"ios-background-downloads","depth":3,"children":[]},{"title":"autoDetectCompanionFiles","slug":"autodetectcompanionfiles","depth":3,"children":[]},{"title":"Swift ergonomics","slug":"swift-ergonomics","depth":3,"children":[]},{"title":"Memory-mapped model loading by default","slug":"memory-mapped-model-loading-by-default","depth":3,"children":[]},{"title":"KV cache reuse across generations","slug":"kv-cache-reuse-across-generations","depth":3,"children":[]}]},{"title":"Per-release notes","slug":"per-release-notes","depth":2,"children":[{"title":"v0.10.7 — 2026-05-18","slug":"v0-10-7-—-2026-05-18","depth":3,"children":[]},{"title":"v0.10.6 — 2026-05-12","slug":"v0-10-6-—-2026-05-12","depth":3,"children":[]},{"title":"v0.10.5 — 2026-05-11","slug":"v0-10-5-—-2026-05-11","depth":3,"children":[]},{"title":"v0.10.4.5 — 2026-05-08","slug":"v0-10-4-5-—-2026-05-08","depth":3,"children":[]},{"title":"v0.10.4.4 — 2026-05-07","slug":"v0-10-4-4-—-2026-05-07","depth":3,"children":[]},{"title":"v0.10.4.3 — 2026-05-07","slug":"v0-10-4-3-—-2026-05-07","depth":3,"children":[]},{"title":"v0.10.4.1 — 2026-05-07","slug":"v0-10-4-1-—-2026-05-07","depth":3,"children":[]},{"title":"v0.10.4 — 2026-05-06","slug":"v0-10-4-—-2026-05-06","depth":3,"children":[]},{"title":"v0.10.1 — 2026-04-29","slug":"v0-10-1-—-2026-04-29","depth":3,"children":[]},{"title":"v0.10.0 — 2026-04-28","slug":"v0-10-0-—-2026-04-28","depth":3,"children":[]}]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/liquidai/2144e9fe91464dd7/styles.js","/_mintlify/custom/liquidai/0cc8a3022b0538e7/feedback-ack.js"],"subdomain":"liquidai","siteName":"Liquid AI Docs","title":"Changelog - Liquid AI Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-13T21:06:39.108Z","originalFileLocation":"deployment/on-device/leap-sdk-changelog.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"light\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Liquid AI Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Changelog - Liquid AI Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Liquid AI Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.liquid.ai/deployment/on-device/leap-sdk-changelog\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://liquidai.mintlify.site/_mintlify/api/og/v2?division=Documentation\u0026amp;title=Changelog\u0026amp;description=Release+notes+for+the+LEAP+SDK%2C+including+the+0.9.x+%E2%86%92+0.10.x+Kotlin+Multiplatform+transition.\u0026amp;theme=163a94b2c7e20fa5bc820924\u0026amp;signature=ab2bbcba677cf9254b8e27aee17c9e9484ac45c4bae326c9306bfcffd36ce94f\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Changelog - Liquid AI Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://liquidai.mintlify.site/_mintlify/api/og/v2?division=Documentation\u0026amp;title=Changelog\u0026amp;description=Release+notes+for+the+LEAP+SDK%2C+including+the+0.9.x+%E2%86%92+0.10.x+Kotlin+Multiplatform+transition.\u0026amp;theme=163a94b2c7e20fa5bc820924\u0026amp;signature=ab2bbcba677cf9254b8e27aee17c9e9484ac45c4bae326c9306bfcffd36ce94f\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/liquidai/phtMVWJKuJHaYPbP/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Liquid AI Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#7c3aed\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.liquid.ai/deployment/on-device/leap-sdk-changelog\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/deployment/on-device/leap-sdk-changelog.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://www.liquid.ai/#organization\",\"name\":\"Liquid AI\",\"url\":\"https://www.liquid.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://docs.liquid.ai/logo/light.svg\"},\"sameAs\":[\"https://huggingface.co/LiquidAI\",\"https://github.com/Liquid4All\",\"https://x.com/liquidai\",\"https://www.linkedin.com/company/liquid-ai-inc\",\"https://www.youtube.com/channel/UClzRQA8Un3AJnlD6h1hv6fA\"]},{\"@type\":\"WebSite\",\"@id\":\"https://docs.liquid.ai#website\",\"name\":\"Liquid AI Docs\",\"url\":\"https://docs.liquid.ai\",\"publisher\":{\"@id\":\"https://www.liquid.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.liquid.ai/deployment/on-device/leap-sdk-changelog#webpage\",\"url\":\"https://docs.liquid.ai/deployment/on-device/leap-sdk-changelog\",\"name\":\"Changelog\",\"description\":\"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.\",\"dateModified\":\"2026-11-13T21:06:39.108Z\",\"isPartOf\":{\"@id\":\"https://docs.liquid.ai#website\"}},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.liquid.ai/deployment/on-device/leap-sdk-changelog#article\",\"headline\":\"Changelog\",\"name\":\"Changelog\",\"description\":\"Release notes for the LEAP SDK, including the 0.9.x → 0.10.x Kotlin Multiplatform transition.\",\"url\":\"https://docs.liquid.ai/deployment/on-device/leap-sdk-changelog\",\"mainEntityOfPage\":{\"@id\":\"https://docs.liquid.ai/deployment/on-device/leap-sdk-changelog#webpage\"},\"dateModified\":\"2026-11-13T21:06:39.108Z\",\"publisher\":{\"@id\":\"https://www.liquid.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.liquid.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Liquid AI Docs\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Liquid AI\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/deployment/on-device/leap-sdk-changelog.md","siteName":"Liquid AI Docs","nav":{"global":null,"tabs":[{"tab":"LFM","groups":[{"group":"LFM","pages":[{"group":"Models","icon":"brain","expanded":false,"pages":[{"group":"Liquid Foundation Models","root":{"title":"Liquid Foundation Models","href":"/lfm/models/complete-library"},"expanded":false,"pages":[{"title":"Text Models","icon":"comment","href":"/lfm/models/text-models"},{"title":"Vision Models","icon":"eye","href":"/lfm/models/vision-models"},{"title":"Audio Models","icon":"headphones","href":"/lfm/models/audio-models"},{"title":"Omni Models","icon":"circle-nodes","href":"/lfm/models/omni-models"},{"title":"Decision Models","icon":"scale-balanced","href":"/lfm/models/decision-models"},{"title":"Liquid Nanos","icon":"sparkles","href":"/lfm/models/liquid-nanos"}]},{"title":"Chat Template","href":"/lfm/key-concepts/chat-template"},{"title":"Prompting Guide","href":"/lfm/key-concepts/text-generation-and-prompting"},{"title":"Tool Use","href":"/lfm/key-concepts/tool-use"},{"title":"Vision Capabilities","href":"/lfm/key-concepts/vision-capabilities"},{"title":"Audio Capabilities","href":"/lfm/key-concepts/audio-capabilities"},{"title":"Omni Capabilities","href":"/lfm/key-concepts/omni-capabilities"},{"title":"Speculative Decoding","href":"/lfm/key-concepts/speculative-decoding"}]},{"group":"Fine-tuning","icon":"sliders","expanded":false,"pages":[{"title":"Overview","href":"/lfm/fine-tuning/overview"},{"title":"Liquid Finetune","href":"/lfm/fine-tuning/liquid-finetune"},{"title":"Datasets","href":"/lfm/fine-tuning/datasets"},{"title":"TRL","href":"/lfm/fine-tuning/trl"},{"title":"Unsloth","href":"/lfm/fine-tuning/unsloth"},{"title":"Halo","href":"/lfm/fine-tuning/halo"}]},{"group":"Edge Inference","icon":"mobile","expanded":false,"pages":[{"title":"llama.cpp","href":"/deployment/on-device/llama-cpp"},{"title":"iOS \u0026 Android","href":"/deployment/on-device/llama-cpp/mobile"},{"title":"LM Studio","href":"/deployment/on-device/lm-studio"},{"title":"MLX","href":"/deployment/on-device/mlx"},{"title":"ONNX","href":"/deployment/on-device/onnx"},{"title":"Ollama","href":"/deployment/on-device/ollama"},{"title":"Atomic Chat","href":"/deployment/on-device/atomic-chat"},{"title":"Llama","href":"/deployment/on-device/llama"}]},{"group":"GPU Inference","icon":"microchip","expanded":false,"pages":[{"title":"Transformers","href":"/deployment/gpu-inference/transformers"},{"title":"SGLang","href":"/deployment/gpu-inference/sglang"},{"title":"vLLM","href":"/deployment/gpu-inference/vllm"},{"title":"zml/llmd","href":"/deployment/gpu-inference/zml-llmd"}]},{"group":"Cloud Inference","icon":"cloud","expanded":false,"pages":[{"title":"Modal","href":"/deployment/gpu-inference/modal"},{"title":"Baseten","href":"/deployment/gpu-inference/baseten"},{"title":"Fal","href":"/deployment/gpu-inference/fal"}]},{"group":"Guides","icon":"book-open","expanded":false,"pages":[{"title":"Hardware Evaluation","href":"/guides/hardware-evaluation"},{"title":"Use Case Evaluation","href":"/guides/use-case-evaluation"},{"title":"Migration Guide","href":"/guides/migration-guide"},{"title":"Decision Model Guide","href":"/guides/decision-model-guide"}]},{"group":"Help","icon":"book","expanded":false,"pages":[{"title":"FAQs","href":"/lfm/help/faqs"},{"title":"Troubleshooting","href":"/lfm/help/troubleshooting"},{"title":"Deprecations","href":"/lfm/help/deprecations"},{"title":"Contributing to Docs","href":"/lfm/help/contributing"},{"title":"Connect AI Tools","href":"/lfm/help/connect-ai-tools"},{"title":"LFM Open License User Guide","href":"/lfm/help/model-license"},{"title":"Model Documentation","href":"/lfm/help/model-documentation"}]}]}]},{"tab":"API","groups":[{"group":"API","pages":[{"group":"Get started","icon":"rocket","expanded":false,"pages":[{"title":"Liquid API","sidebarTitle":"Overview","href":"/api/overview"},{"title":"Developer quickstart","sidebarTitle":"Quickstart","href":"/api/quickstart"},{"title":"Models","href":"/api/models"}]},{"group":"Capabilities","icon":"wand-magic-sparkles","expanded":false,"pages":[{"title":"Text generation","href":"/api/guides/text-generation"},{"title":"Vision","href":"/api/guides/vision"},{"title":"Audio and speech","sidebarTitle":"Audio and speech","href":"/api/guides/audio"},{"title":"Decisions","href":"/api/guides/decisions"}]},{"group":"Platform","icon":"server","expanded":false,"pages":[{"title":"Batch","href":"/api/guides/batch"},{"title":"Your data","href":"/api/guides/your-data"}]}]}]},{"tab":"API reference","groups":[{"group":"API reference","pages":[{"group":"API reference","icon":"code","expanded":false,"pages":[{"title":"Overview","href":"/api/reference/overview"},{"title":"Rate limits","href":"/api/reference/rate-limits"},{"title":"Error codes","href":"/api/reference/error-codes"},{"group":"Endpoints","expanded":true,"pages":[{"group":"Models","pages":[{"title":"List models","deprecated":null,"version":null,"openapi":"/api/openapi.json get /openai/v1/models","href":"/api/reference/models/list-models"},{"title":"Retrieve model","deprecated":null,"version":null,"openapi":"/api/openapi.json get /openai/v1/models/{model}","href":"/api/reference/models/retrieve-model"}]},{"group":"Chat","pages":[{"title":"Chat completions","deprecated":null,"version":null,"openapi":"/api/openapi.json post /openai/v1/chat/completions","href":"/api/reference/chat/chat-completions"}]},{"group":"Decision models","pages":[{"title":"Make decisions","deprecated":null,"version":null,"openapi":"/api/openapi.json post /decisions/v1/systemone","href":"/api/reference/decision-models/make-decisions"},{"title":"List decision models","deprecated":null,"version":null,"openapi":"/api/openapi.json get /decisions/v1/models","href":"/api/reference/decision-models/list-decision-models"}]},{"group":"Files","pages":[{"title":"List files","deprecated":null,"version":null,"openapi":"/api/openapi.json get /openai/v1/files","href":"/api/reference/files/list-files"},{"title":"Retrieve file","deprecated":null,"version":null,"openapi":"/api/openapi.json get /openai/v1/files/{id}","href":"/api/reference/files/retrieve-file"},{"title":"Retrieve file content","deprecated":null,"version":null,"openapi":"/api/openapi.json get /openai/v1/files/{id}/content","href":"/api/reference/files/retrieve-file-content"}]},{"group":"Batches","pages":[{"title":"List batches","deprecated":null,"version":null,"openapi":"/api/openapi.json get /openai/v1/batches","href":"/api/reference/batches/list-batches"},{"title":"Create batch","deprecated":null,"version":null,"openapi":"/api/openapi.json post /openai/v1/batches","href":"/api/reference/batches/create-batch"},{"title":"Retrieve batch","deprecated":null,"version":null,"openapi":"/api/openapi.json get /openai/v1/batches/{id}","href":"/api/reference/batches/retrieve-batch"},{"title":"Cancel batch","deprecated":null,"version":null,"openapi":"/api/openapi.json post /openai/v1/batches/{id}/cancel","href":"/api/reference/batches/cancel-batch"}]},{"group":"Large uploads","pages":[{"title":"Create upload URL","deprecated":null,"version":null,"openapi":"/api/openapi.json post /v1/files","href":"/api/reference/large-uploads/create-upload-url"}]}]}]}]}]},{"tab":"Examples","groups":[{"group":"Examples","pages":[{"group":"Getting Started","icon":"rocket","expanded":false,"pages":[{"title":"Examples Library","href":"/examples"},{"title":"Connect AI Tools","href":"/examples/connect-ai-tools"},{"title":"Run local agents with LFMs","href":"/examples/agent-harnesses"}]},{"group":"Laptop Examples","icon":"laptop","expanded":false,"pages":[{"title":"Invoice extractor tool","href":"/examples/laptop-examples/invoice-extractor-tool-with-liquid-nanos"},{"title":"Build a game with decision models","href":"/examples/laptop-examples/build-a-game-with-decision-models"},{"title":"Audio transcription in real-time","href":"/examples/laptop-examples/audio-to-text-in-real-time"},{"title":"Bidirectional English to Korean translation CLI","href":"/examples/laptop-examples/lfm2-english-to-korean"},{"title":"Flight search assistant with tool calling","href":"/examples/laptop-examples/flight-search-assistant"},{"title":"Audio car cockpit demo","href":"/examples/laptop-examples/audio-car-cockpit"},{"title":"Meeting summarization CLI","href":"/examples/laptop-examples/meeting-summarization"},{"title":"Browser control with GRPO reinforcement learning","href":"/examples/laptop-examples/browser-control"}]},{"group":"Android Examples","icon":"robot","expanded":false,"pages":[{"title":"Product Slogan Generator with LeapSDK","href":"/examples/android/slogan-generator"},{"title":"Web Content Summarizer for Android","href":"/examples/android/web-content-summarizer"},{"title":"Generate Structured Recipes with Constrained Output","href":"/examples/android/recipe-generator-constrained-output"},{"title":"Image Understanding with Vision Language Models","href":"/examples/android/vision-language-model-example"},{"title":"Build AI Agents with Koog Framework on Android","href":"/examples/android/leap-koog-agent"}]},{"group":"Web Examples","icon":"globe","expanded":false,"pages":[{"title":"Real-time video captioning with LFM2.5-VL-1.6B and WebGPU","href":"/examples/web/vl-webgpu-demo"},{"title":"LFM2.5-Audio browser demo with WebGPU","href":"/examples/web/audio-webgpu-demo"},{"title":"Hand \u0026 Voice Racer","href":"/examples/web/hand-voice-racer"}]},{"group":"Model Customization","icon":"sliders","expanded":false,"pages":[{"title":"Fine tuning LFM2-VL to identify car makers from images","href":"/examples/customize-models/car-maker-identification"},{"title":"Fine-tuning LFM for a local Home Assistant","href":"/examples/customize-models/home-assistant"},{"title":"Fine-Tune a Vision-Language Model on Satellite Imagery","href":"/examples/customize-models/satellite-vlm"},{"title":"Build a Wildfire Prevention System with a Compact VLM","href":"/examples/customize-models/wildfire-prevention"}]}]}]}]},"basePath":"","title":"Changelog - Liquid AI Docs","buildId":"dpl_715YoAgvjTGBDdo8RtXmHKM22b5p","deploymentId":"dpl_715YoAgvjTGBDdo8RtXmHKM22b5p","dynamics":["10e4515597"],"chunks":["BannerMarkdown-DwP8r2Xt.js","dist-r2tNEC1n.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","clsx-BNa-H6W6.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js"]}