fix(sdk): apply v0.10.6 Android SDK doc QA fixes (DOC-27, DOC-37..DOC-60)#97
fix(sdk): apply v0.10.6 Android SDK doc QA fixes (DOC-27, DOC-37..DOC-60)#97iamstuffed wants to merge 26 commits into
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
Pull request overview
This PR applies a comprehensive doc-QA pass across the Android (and cross-platform Kotlin) sections of the on-device SDK documentation against the v0.10.6 SDK release. It updates outdated import paths, replaces removed/renamed APIs in example snippets, corrects the Swift exportToJSON() return type, and removes a legacy leap/edge-sdk/overview.mdx stub that was blocking a redirect. Examples under examples/android/ are updated to match the same v0.10.6 API surface.
Changes:
- Update Kotlin imports (
model_downloader→downloader, top-level helpers →manifestpackage,MessageResponsefromai.liquid.leap→ai.liquid.leap.message) and replace removedChatMessage.user(...)factory with the primaryChatMessage(role, ...)constructor across docs and examples. - Replace removed/renamed Kotlin APIs:
setResponseFormatType(KClass)→ reifiedsetResponseFormatType<T>();LeapModelDownloaderconstructor signature (dropextraHTTPRequestHeaders, adddownloaderConfig/ioDispatcher, make request methodssuspend, deprecaterequestStopService);ChatMessageContentshape (Image(ImageUrl),Audio(InputAudio), removedtoJSONObject/fromJSONObjectin favor ofkotlinx.serialization);LeapFunctionParameterTypenested-class names nowLeap-prefixed;getPromptTokensSizeelevated toModelRunner; SwiftConversation.exportToJSON()returnsString(non-throwing). - Update voice-assistant snippet to send
AudioPcmF32directly instead of WAV re-encoding, and delete the legacyleap/edge-sdk/overview.mdxstub.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| leap/edge-sdk/overview.mdx | Removes legacy stub so the /leap/edge-sdk/overview redirect can take effect. |
| examples/android/web-content-summarizer.mdx | Update downloader import and ChatMessage construction. |
| examples/android/vision-language-model-example.mdx | Update downloader import. |
| examples/android/slogan-generator.mdx | Update downloader import and ChatMessage construction. |
| examples/android/recipe-generator-constrained-output.mdx | Update downloader import, reified setResponseFormatType, primary ChatMessage ctor. |
| examples/android/leap-koog-agent.mdx | Update downloader import. |
| deployment/on-device/sdk/voice-assistant.mdx | Update downloader import, reorder/correct imports, send raw float32 PCM instead of WAV. |
| deployment/on-device/sdk/utilities.mdx | Swift exportToJSON() now returns String; updated Kotlin LeapModelDownloader reference signature, nested ModelDownloadStatus, suspend/deprecation notes; reified setResponseFormatType and primary ChatMessage ctor. |
| deployment/on-device/sdk/quick-start.mdx | Downloader package rename, notification field rename, manifest-package imports, primary ChatMessage ctor. |
| deployment/on-device/sdk/openai-client.mdx | Correct MessageResponse import path. |
| deployment/on-device/sdk/model-loading.mdx | Updated LeapModelDownloader reference signature; removed obsolete ModelLoadingOptions.build. |
| deployment/on-device/sdk/messages-content.mdx | New ChatMessage secondary ctor, switch from JSONObject helpers to kotlinx.serialization, new ChatMessageContent (ImageUrl/InputAudio) shape, ImageUtils.fromBitmap suspend helper. |
| deployment/on-device/sdk/desktop-platforms.mdx | Imports moved to ai.liquid.leap.manifest; primary ChatMessage ctor. |
| deployment/on-device/sdk/conversation-generation.mdx | Swift exportToJSON() returns String; remove Kotlin exportToJSONArray / non-reified setResponseFormatType; document kotlinx.serialization round-trip. |
| deployment/on-device/sdk/constrained-generation.mdx | Reified setResponseFormatType/getJSONSchema; switch JSON parsing to kotlinx.serialization; rename createFromJSONObject → createFromJsonObject. |
| deployment/on-device/sdk/ai-agent-usage-guide.mdx | Correct MessageResponse and LeapModelDownloader import paths. |
| deployment/on-device/sdk/advanced-features.mdx | Reified setResponseFormatType; renamed LeapFunctionParameterType nested classes (LeapStr, LeapNum, etc.); getPromptTokensSize now on ModelRunner and is suspend. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ction
- `ai.liquid.leap.model_downloader.*` → `ai.liquid.leap.downloader.*` for `LeapModelDownloader` and `LeapModelDownloaderNotificationConfig` (DOC-27).
- `notificationContentDownloading` → `notificationContentDownloadingTemplate` to match the real `LeapModelDownloaderNotificationConfig` field (DOC-37).
- JVM section: `ai.liquid.leap.LeapDownloader{,Config}` → `ai.liquid.leap.manifest.LeapDownloader{,Config}` (DOC-38).
- Replace 4× `ChatMessage.user(...)` (no such companion factory) with the real primary/secondary constructors (DOC-39).
Verified against leap-android-sdk v0.10.6 (commit cac3d06):
leap-sdk-model-downloader/src/androidMain/.../LeapModelDownloader.kt,
LeapModelDownloaderNotificationConfig.kt,
leap-sdk/src/commonMain/.../message/ChatMessage.kt,
leap-sdk/src/commonMain/.../manifest/LeapDownloader.kt.
Refs DOC-27, DOC-37, DOC-38, DOC-39.
…elLoadingOptions.build
- Rewrite the Kotlin (Android) `LeapModelDownloader` class block to the real 5-parameter primary constructor: `(Context, File?, LeapModelDownloaderNotificationConfig, LeapDownloaderConfig, CoroutineDispatcher)`. The doc previously listed a 4-parameter signature with a nonexistent `extraHTTPRequestHeaders` field (DOC-40).
- Drop the nonexistent `ModelLoadingOptions.Companion.build { ... }` factory from the Kotlin block and the example; switch the example to the direct primary-constructor form `ModelLoadingOptions(cpuThreads = 6, contextSize = 4096)`. `GenerationOptions.build {}` still exists and is unaffected; only `ModelLoadingOptions.build` was bogus (DOC-41).
Verified against leap-android-sdk v0.10.6 (commit cac3d06):
leap-sdk-model-downloader/src/androidMain/.../LeapModelDownloader.kt:56,
leap-sdk/src/commonMain/.../ModelLoadingOptions.kt:6.
Refs DOC-40, DOC-41.
… imports - `import ai.liquid.leap.MessageResponse` → `import ai.liquid.leap.message.MessageResponse` (DOC-43). - `import ai.liquid.leap.model_downloader.LeapModelDownloader` → `import ai.liquid.leap.downloader.LeapModelDownloader` (DOC-42). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/MessageResponse.kt, leap-sdk-model-downloader/src/androidMain/.../downloader/LeapModelDownloader.kt. Refs DOC-42, DOC-43.
…e-format API + Swift export return type - Drop the nonexistent `fun exportToJSONArray(): JSONArray` from the Kotlin `Conversation` interface block; switch the Kotlin "Export chat history" example to `kotlinx.serialization.encodeToString(conversation.history)` per the existing Utilities → Serialization pattern (DOC-44). - Drop the nonexistent `fun setResponseFormatType(kClass: KClass<*>)` overload from the documented `GenerationOptions` companion; switch the example to the real `inline fun <reified T> setResponseFormatType()` (DOC-60). Also fix a related bug not flagged by QA: Swift `Conversation.exportToJSON()` returns `String` (per `leap-sdk/src/appleMain/.../compat/ConversationExtensions.kt:45`), not `throws -> [[String: Any]]`. Updated the Swift interface block and Swift snippet accordingly. Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../Conversation.kt, leap-sdk/src/commonMain/.../GenerationOptions.kt:126, leap-sdk/src/appleMain/.../compat/ConversationExtensions.kt:45. Refs DOC-44, DOC-60.
… reference - Drop the nonexistent `ChatMessage.toJSONObject()` / `ChatMessage.Companion.fromJSONObject(obj)` from the Kotlin data-class block; point the Kotlin Serialization tab at `kotlinx.serialization.Json.encodeToString` / `decodeFromString` (DOC-45). - Rewrite the Kotlin `ChatMessageContent` reference block: it is a `sealed class`, not `sealed interface`; drop the nonexistent `fun clone()` / `fun toJSONObject()` members and the nonexistent top-level `ChatMessageContent.fromJSONObject(obj)` extension (DOC-46). - Replace the documented `Image(jpegByteArray: ByteArray)` / `Audio(wavByteArray: ByteArray)` primary constructors with the real `Image(imageUrl: ImageUrl)` / `Audio(inputAudio: InputAudio)` and call out the convenience secondary constructors plus the derived `jpegByteArray` / `data` properties (DOC-47). - Replace `ChatMessageContent.Image.fromBitmap(...)` (no such companion method) with the real Android-only `ai.liquid.leap.message.ImageUtils.fromBitmap(Bitmap, Int)` (note: `suspend`) (DOC-48). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/ChatMessage.kt:10, leap-sdk/src/commonMain/.../message/ChatMessageContent.kt:15, leap-sdk/src/androidMain/.../message/ImageUtils.kt. Refs DOC-45, DOC-46, DOC-47, DOC-48.
… APIs - `JSONSchemaGenerator.getJSONSchema(CityFact::class)` → `JSONSchemaGenerator.getJSONSchema<CityFact>()`. The real method has a reified-T form and a `KSerializer<T>` form — no `KClass` overload (DOC-49). - `GeneratableFactory.createFromJSONObject(JSONObject(jsonContent))` → `GeneratableFactory.createFromJsonObject<T>(kxObj)`. Two bugs in one line: method name uses camelCase `Json` (not `JSON`), and the argument is `kotlinx.serialization.json.JsonObject` (not `org.json.JSONObject`) (DOC-50). - `setResponseFormatType(CityFact::class)` → `setResponseFormatType<CityFact>()` (DOC-60). - Update the prose, "Apply the schema" example, the schema-injection helper, and the Best-Practices parser snippet to use the corrected APIs consistently. Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../structuredoutput/JSONSchemaGenerator.kt, leap-sdk/src/commonMain/.../structuredoutput/GeneratableFactory.kt, leap-sdk/src/commonMain/.../GenerationOptions.kt:126. Refs DOC-49, DOC-50, DOC-60.
…Pcm16Wav helper - `import ai.liquid.leap.MessageResponse` → `import ai.liquid.leap.message.MessageResponse` (DOC-51). - `import ai.liquid.leap.model_downloader.LeapModelDownloader` → `import ai.liquid.leap.downloader.LeapModelDownloader` (DOC-52). - Drop the import and call of `ai.liquid.leap.message.encodePcm16Wav(...)` — no such top-level function exists in v0.10.6. Switch the Kotlin `LeapVoiceConversation.generateResponse` example to `ChatMessageContent.AudioPcmF32(audioSamples, sampleRate)`, which skips the WAV re-encode entirely (DOC-53). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/MessageResponse.kt, leap-sdk-model-downloader/src/androidMain/.../downloader/LeapModelDownloader.kt, leap-sdk/src/commonMain/.../message/ChatMessageContent.kt (AudioPcmF32 variant), no occurrence of encodePcm16Wav in leap-sdk/src. Refs DOC-51, DOC-52, DOC-53.
- `ai.liquid.leap.LeapDownloader` → `ai.liquid.leap.manifest.LeapDownloader` (DOC-54, issue 25).
- `ai.liquid.leap.LeapDownloaderConfig` → `ai.liquid.leap.manifest.LeapDownloaderConfig` (DOC-54, issue 26).
- `ai.liquid.leap.ModelSource` → `ai.liquid.leap.manifest.ModelSource` (DOC-54, issue 27).
- Replace `ChatMessage.user("What is the capital of France?")` (nonexistent companion factory — same as DOC-39) with `ChatMessage(ChatMessage.Role.USER, "What is the capital of France?")`.
Verified against leap-android-sdk v0.10.6 (commit cac3d06):
leap-sdk/src/commonMain/.../manifest/LeapDownloader.kt,
leap-sdk/src/commonMain/.../manifest/LeapDownloaderConfig.kt,
leap-sdk/src/commonMain/.../manifest/ModelSource.kt,
leap-sdk/src/commonMain/.../message/ChatMessage.kt.
Refs DOC-54, DOC-39.
…nloadStatus - Rewrite the Kotlin status-polling block to match the real v0.10.6 surface: * `LeapModelDownloader` primary constructor has 5 parameters: `(Context, File?, LeapModelDownloaderNotificationConfig, LeapDownloaderConfig, CoroutineDispatcher)`. The previous block listed a nonexistent `extraHTTPRequestHeaders` field (same as DOC-40). * `requestDownloadModel` is `suspend` (DOC-55, issue 28). * `requestStopDownload` is `suspend` (DOC-55, issue 29). * `requestStopService` is `@Deprecated` *and* `suspend` (DOC-55, issue 30). * `ModelDownloadStatus` is nested under `LeapModelDownloader` — there is no top-level `ai.liquid.leap.downloader.ModelDownloadStatus` (DOC-56). - Update the bullet list under the block to reflect the new modifiers and deprecation. - Putting-it-together example: replace `setResponseFormatType(TripRecommendation::class)` with `setResponseFormatType<TripRecommendation>()` (DOC-60) and replace `ChatMessage.user(...)` with the real constructor (DOC-39). - Fix a related Swift bug not flagged by QA: `Conversation.exportToJSON()` returns `String`, not `throws -> [[String: Any]]` (per leap-sdk/src/appleMain/.../ConversationExtensions.kt:45). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk-model-downloader/src/androidMain/.../downloader/LeapModelDownloader.kt (lines 56, 268, 349, 374, 450, 501). Refs DOC-55, DOC-56, DOC-39, DOC-60.
…nd drop bogus runner cast - Rewrite the Kotlin `LeapFunctionParameterType` nested classes to the real names with a `Leap` prefix — `LeapStr`, `LeapNum`, `LeapInt`, `LeapBool`, `LeapNull`, `LeapArr`, `LeapObj`. The prefix exists upstream specifically to avoid shadowing `kotlin.String`, `kotlin.Number`, etc., and the Function Calling guide on the adjacent page already uses these names (DOC-57, issues 32–38). - Remove the `runner as? LiquidInferenceEngineRunner` cast around `getPromptTokensSize`. `getPromptTokensSize(messages:, addBosToken:)` is declared directly on the cross-platform `ModelRunner` interface in v0.10.6, so no cast is needed. `LiquidInferenceEngineRunner` only exists as an Apple compat class at `ai.liquid.leap.compat.LiquidInferenceEngineRunner` — there is no `ai.liquid.leap.LiquidInferenceEngineRunner`, and on Kotlin Android the cast was always unresolved (DOC-58). - Drop the nonexistent `fun setResponseFormatType(kClass: KClass<*>)` overload from the documented Kotlin `GenerationOptions` companion; the only real method is `inline fun <reified T> setResponseFormatType()` (DOC-60). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../function/LeapFunctionParameterType.kt, leap-sdk/src/commonMain/.../ModelRunner.kt:39, leap-sdk/src/commonMain/.../GenerationOptions.kt:126, leap-sdk/src/appleMain/.../compat/LiquidInferenceEngineRunner.kt. Refs DOC-57, DOC-58.
- `import ai.liquid.leap.MessageResponse` → `import ai.liquid.leap.message.MessageResponse` in the hybrid on-device + cloud routing Kotlin (Android) snippet. Real package is `ai.liquid.leap.message`, same as DOC-43 and DOC-51 on other pages (DOC-59). Verified against leap-android-sdk v0.10.6 (commit cac3d06): leap-sdk/src/commonMain/.../message/MessageResponse.kt. Refs DOC-59.
…mple pages The example pages under examples/android/ had the same outdated patterns flagged by the QA pass on the SDK reference pages: - Wrong import package `ai.liquid.leap.model_downloader.LeapModelDownloader` → `ai.liquid.leap.downloader.LeapModelDownloader` across all 5 files (DOC-27 root cause). - `setResponseFormatType(Recipe::class)` → `setResponseFormatType<Recipe>()` plus the matching prose mention in recipe-generator-constrained-output.mdx (DOC-60 root cause). - `ChatMessage.user(prompt)` → `ChatMessage(ChatMessage.Role.USER, prompt)` across recipe-generator-constrained-output, slogan-generator, and web-content-summarizer (DOC-39 root cause). Verified against leap-android-sdk v0.10.6 (commit cac3d06). Refs DOC-27, DOC-39, DOC-60.
…ct fires The file at leap/edge-sdk/overview.mdx was a leftover from the pre-unification "LEAP Edge SDK" page tree. docs.json already redirects `/leap/edge-sdk/overview` → `/deployment/on-device/sdk/quick-start`, but Mintlify prefers existing files over redirect rules, so the legacy page kept rendering with broken internal links (e.g. `./ios/ios-quick-start-guide`). Removing the file lets the redirect fire. Verified with `npx mintlify dev` after deletion: GET /leap/edge-sdk/overview → 307 /deployment/on-device/sdk/quick-start. All 27 previously-known-good legacy URLs (10 android/, 10 ios/, plus :slug* wildcards and the Edge SDK paths) now return 3xx redirects to the unified /deployment/on-device/sdk/* tree.
…leFactory reference signatures Audit follow-up. The reference signature blocks for `JSONSchemaGenerator` and `GeneratableFactory` in this page still showed the pre-v0.10.6 surface — a `KClass` overload for both, and `JSONObject` (the `org.json` type) on the factory. Real signatures (verified against `leap-sdk/src/commonMain/.../structuredoutput/JSONSchemaGenerator.kt` and `GeneratableFactory.kt`): - `JSONSchemaGenerator.getJSONSchema(serializer: KSerializer<T>, indentSpaces: Int? = null): String` plus the reified-T form. No `KClass` overload. - `GeneratableFactory.createFromJsonObject(jsonObject: kotlinx.serialization.json.JsonObject, serializer: KSerializer<T>): T` plus the reified-T form. Note camelCase `Json` in the method name and the `kotlinx.serialization.json.JsonObject` argument (not `org.json.JSONObject`). The working code snippets on this page and on `constrained-generation.mdx` already use the correct reified syntax — only the reference tables were stale. Same root cause as DOC-49 and DOC-50; tightening the reference signatures so they match the example usage. Refs DOC-49, DOC-50.
`ChatMessageContent.Image(jpegByteArray: ByteArray)` is a convenience secondary constructor that wraps the bytes in a `data:image/jpeg;base64,...` URL (see `leap-sdk/src/commonMain/.../message/ChatMessageContent.kt` — `JPEG_BASE64_DATA_URL_PREFIX` is hard-coded). Passing PNG bytes still compiles but produces a content-type mismatch on the wire that the model will reject or misinterpret. Switch the example to `ImageUtils.fromBitmap(bitmap, compressionQuality = 85)` — the canonical Android helper, which JPEG-encodes via `Bitmap.compress(JPEG, ...)` on `Dispatchers.Default` and returns a `ChatMessageContent.Image` ready to send. Drop the now-unused `ByteArrayOutputStream` import. Refs DOC-48.
…redoutput package @Generatable and @Guide are declared in ai.liquid.leap.structuredoutput (Annotations.kt) and are not re-exported from the top-level ai.liquid.leap package. Copy-pasting the original snippet failed with 'unresolved reference'. Refs DOC-49/50, DOC-60.
8b13e7f to
6650914
Compare
…ated Swift APIs
JSONSchemaGenerator throws LeapGeneratableSchematizationException("Type must be
@serializable to generate JSON Schema") when the type lacks @serializable
(leap-sdk/src/commonMain/.../JSONSchemaGenerator.kt:53-59), so the CityFact,
Recipe, and NutritionInfo snippets were runtime-broken. @Generatable requires a
description (no Kotlin default) and @Guide is @target(AnnotationTarget.PROPERTY)
only (Annotations.kt:14,21), so the recipe-generator example with
class-level @Guide and no @Generatable description was compile-broken.
Also corrects the Swift side: setResponseFormat(type:) does not exist (canonical
path is options.with(jsonSchema: T.jsonSchema()), or
GenerationOptionsCompat.setResponseFormat(jsonSchema:)),
JSONSchemaGenerator.getJSONSchema(for:) is non-throwing (no try), and
LeapSDKMacros must be imported alongside LeapModelDownloader. Replaces the
"computed via reflection" claim with the actual mechanism (kotlinx.serialization
descriptor) and drops the misleading 0.7 default-temperature reference per
project CLAUDE.md guidance.
…cated VLM API leap-koog-agent: Apps cannot read /tmp/ on Android — switch the ADB commands and modelPath to /data/local/tmp/liquid/ (matches recipe-generator and VLM example). Drop the inconsistent .bundle filename reference; the SDK ships GGUFs. vision-language-model-example: the page mixed LFM2-VL-1.6B and LFM2.5-VL-1.6B — unify on LFM2.5-VL-1.6B (matches the actual ModelSource(modelName: "LFM2.5-VL-1.6B") load call). Replace the askQuestionAboutImage snippet that called the nonexistent vlmModel.generateFromImage(image, prompt, maxTokens:) with the real ImageUtils.fromBitmap + Conversation.generateResponse pipeline. Rewrite the lifecycle section to call ModelRunner.unload() (suspend) with a re-entrance guard instead of the made-up releaseModel()/initializeModel() pair.
…Swift factory APIs quick-start: MessageResponse.ReasoningChunk has `reasoning`, not `text` (MessageResponse.kt:50). The previous Kotlin snippet would not compile. Also replace nonexistent Swift .image(jpegData) / .audio(wavData) positional factories with the real ChatMessageContent.fromJPEGData(_:) / .fromWAVData(_:) (ChatMessageContentExtensions.swift:14-58), pass reasoningContent: / functionCalls: explicitly (Kotlin defaults do not propagate through K/N), and steer the Swift GenerationOptions snippet to the canonical parameterless init + .with(...) builder chain. model-loading: DownloadedModelManifest.manifest is typed as Manifest, not ModelManifest (Manifest.kt:30). LiquidInferenceEngineOptions.bundlePath is declared `val`, so the Swift surface is `let`, not `var`. SamplingParameters includes a topK field that was missing from the snippet. Drop the misleading "evictUnusedModel is a no-op" reference — that method is private to the service process and not part of any public API.
…t and Content enum The Swift API is generated by Kotlin/Native + SKIE from the Kotlin types — there is no native Swift `struct ChatMessage`, no `enum ChatMessageContent`, no `ChatMessageRole: String` with raw values, and no `init(from: [String: Any])` on either type. Replace those fabrications with the real bridged-class surface where Kotlin parameter defaults do not propagate (init requires all four args) and the role enum is ChatMessage.Role (no String raw-value backing). Drop the nonexistent ChatMessageContent.fromUIImage(image, compressionQuality:) (JPEG quality is hardcoded to 0.85 in the iOS overlay) and the entirely fictitious fromNSImage helper. Replace .audio(wavData) positional factory calls with the real ChatMessageContent.fromWAVData(_:). Fix the Kotlin secondary constructor parameter name (textContent, not text) per ChatMessage.kt:74-77, and add the nested ImageUrl/InputAudio types + toWavBytes()/toAudio() helpers that were missing. Also corrects the prose: ChatMessageContent is a sealed class, not a sealed interface; LeapSerializationException, not LeapSerializationError.
… + SKIE export
Conversation is a Kotlin interface bridged to Swift as a protocol with `{ get }`
properties, not a Swift class with `let` / `private(set) var`. Swift parameter
labels match the Kotlin parameter names (`function:`, `functions:`,
`message:`) — there are no underscore-labeled `_ function:` / `_ message:`
overloads. Generation methods return `SkieSwiftFlow<MessageResponse>` (iterable
with `for try await`), not `AsyncThrowingStream<MessageResponse, Error>`.
Drop the "Swift only" qualifier on `functions` — the property is on the
Kotlin Conversation interface (Conversation.kt:25), available on every
platform. Change every MessageResponse sealed subtype to `data class`
(MessageResponse.kt:41-83) so equals/hashCode/copy semantics survive.
`GenerationStats.tokenPerSecond` is non-nullable Float; only the parent
`stats: GenerationStats?` is nullable. Replace the fabricated Swift
`setResponseFormat<T>(type:)` and `LeapFunctionCallParserProtocol` types
with the real canonical paths (builder `.with(jsonSchema:)` and the
LeapFunctionCallParser class — there is no Protocol suffix). Switch
GenerationOptions Swift examples from the partial kwarg init (which doesn't
exist because Kotlin defaults don't propagate) to the parameterless init +
`.with(...)` builder chain from ConvenienceExtensions.swift.
utilities: LeapError is a typealias for LeapException (Kotlin open class), not a Swift enum — replace fabricated cases (.modelLoadingFailure, .generationFailure, .promptExceedContextLengthFailure, .serializationFailure) with the real LeapException subclass names (LeapException.kt:21-38). Drop the nonexistent onErrorCallback reference and the fictitious ChatMessage(from: [String: Any]) initializer. Note that ModelDownloadStatus nesting differs by platform (Android: nested under LeapModelDownloader; Apple: top-level with a different payload — DownloadInProgress(progress: Double) vs the Android variant). Fix LeapDownloaderConfig.saveDir which takes a String, not a File (so cacheDir needs .absolutePath on Android). Replace the partial-args Swift GenerationOptions init + setResponseFormat(type:) with the builder + jsonSchema form. advanced-features: LeapFunctionCallParserProtocol does not exist — the type is the abstract Kotlin class LeapFunctionCallParser, bridged to Swift as a class with the same name. Remove the fabricated mutating setResponseFormat<T>(type:) — Swift schema setting goes through .with(jsonSchema: T.jsonSchema()) (or GenerationOptionsCompat). Steer the Swift GenerationOptions snippet to the parameterless init + chained .with(...) builders rather than a full-arg init that would require all 13 fields. Add the LeapSDKMacros import for JSONSchemaGenerator and drop the non-throwing-method `try`. Replace the parser-implementation prose with "subclass" since LeapFunctionCallParser is an abstract class on both platforms.
…e Swift labels LeapFunction and LeapFunctionParameter both carry @ObjCName annotations on their description parameters (LeapFunction.kt:19, LeapFunctionParameter at line 71), so the Swift initializer labels are functionDescription: and parameterDescription:, not description:. LeapFunctionParameter.optional has no Swift default — pass optional: false for required parameters (Kotlin defaults don't propagate through K/N + ObjC). The previously documented Swift API (.string(StringType()), .number(NumberType()), .array(ArrayType(...)), .null(NullType) plus their wrapper types) is entirely fabricated. The real Swift surface preserves the Kotlin nested-class names from LeapFunctionParameterType.kt:35-115: LeapFunctionParameterType.LeapStr(enumValues:description:), .LeapNum(enumValues:description:), .LeapInt(enumValues:description:), .LeapBool(description:), .LeapArr(itemType:description:), .LeapObj(properties:required:description:), .LeapNull() (no description). SKIE does NOT generate cleaner .string(...) / .number(...) aliases — the "Swift bindings expose the same primitives under cleaner names" claim was wrong. Rewrites every Swift snippet in the page to use the real class names plus ObjCName-renamed labels, and corrects the LeapFunctionCall.arguments type to [String: Any] (the ObjC bridge collapses Kotlin Any? to non-optional id).
…nce and pin ai-agent-usage-guide: Swift's stdlib has no asyncMap — rewrite the agent loop's tool-execution pass as a sequential `for await` accumulation. Fix the missing `workingConv.` prefix on the Kotlin modelRunner reference (Conversation.kt:16 declares `val modelRunner: ModelRunner` on the interface). Replace .image(jpegData) / .audio(wavData) positional factories with the real ChatMessageContent.fromJPEGData(_:) / .fromWAVData(_:). Add the missing reasoningContent: nil / functionCalls: nil args on every Swift ChatMessage call. Switch the Swift GenerationOptions call to the builder chain. Correct the Kotlin/Native version pin: only v0.10.0, v0.10.1, and v0.10.6 exist on the android-sdk repo (v0.10.2 and v0.10.3 were never tagged); fixes shipped via v0.10.4.x on the SPM repo and v0.10.6 on the android-sdk repo. Pin to 0.10.6 or newer. Annotate the audio.samples access with a note that it's a KotlinFloatArray (needs the floatArrayToNSData bridge before passing to a [Float]-typed renderer). voice-assistant: fraction in downloadProgress is Kotlin Double — cast to Float before passing to setModelProgress(fraction: Float, ...). Add the missing `import android.os.Bundle` to the Compose snippet. Rewrite the AppleVoiceConversation Swift adapter to actually conform to the protocol — the LeapUI VoiceConversation protocol method takes LeapUi.KotlinFloatArray / LeapUi.KotlinInt (the LeapUI and LeapSDK frameworks have separate Kotlin runtimes; cross-framework Kotlin types do not interconvert without an NSData bridge). Add the missing systemPrompt: nil in the Swift modelRunner.createConversation() call (no Swift default). Correct the Compose "transitively" claim — leap-ui depends on Compose with implementation scope, so the runtime artifacts are pulled in but the APIs are not re-exported.
…Swift API
openai-client: the leap-sdk-openai-client Kotlin module does NOT apply the
SKIE plugin (verified in leap-sdk-openai-client/build.gradle.kts:3-11 — only
leap-sdk, leap-sdk-model-downloader, and leap-ui do), so Flow<ChatCompletionEvent>
is not bridged to Swift AsyncSequence and onEnum(of:) is not generated for
ChatCompletionEvent. The "for try await event in client.streamChatCompletion(...)"
+ "switch onEnum(of: event)" Swift example would not compile. Rewrite the
Swift section with a Warning callout explaining the SKIE absence and a manual
Flow.collect(collector: FlowCollector { ... }) + `as?` downcast pattern.
Also corrects the streaming claim: streamChatCompletion(...) forces
request.copy(stream = true) on the outgoing payload (OpenAiClient.kt:49),
overriding whatever stream field the caller set — not a default. Drop the JVM
artifact claim entirely: leap-sdk-openai-client/build.gradle.kts declares no
jvm() target, and Maven Central confirms no leap-openai-client-jvm artifact
exists (https://repo1.maven.org/maven2/ai/liquid/leap/leap-openai-client-jvm/
returns 404). For JVM-only hosts, recommend a standard OpenAI Java/Kotlin SDK.
desktop-platforms: same JVM-artifact correction (drop the commented
`// implementation("ai.liquid.leap:leap-openai-client:0.10.6")` from the JVM
example). Correct the JDK row: leap-sdk's jvm() target inherits
kotlin.jvmToolchain(17) — JDK 11 only applies to the Android target. Correct
the broken-version block: v0.10.2 was never published (only v0.10.0, v0.10.1,
and v0.10.6 on the android-sdk repo); fixes shipped across v0.10.4.x on the
SPM repo and v0.10.6 on the android-sdk repo. Pin to v0.10.6 or newer.
Drop the false Mac Catalyst claim — the released LeapSDK.xcframework slices
are only ios-arm64, ios-arm64-simulator, and macos-arm64. Add a note that the
simulator slice is ARM64-only (no Intel-Mac simulator support). Fix the
mmap-default changelog anchor (#memory-mapped-model-loading-by-default).
cloud-ai-comparison: correct `MessageResponse.functionCalls` to
`MessageResponse.FunctionCalls` (the sealed-variant name, not a property).
Replace the fabricated `GenerationOptions.setResponseFormat(type:)` cell with
the real per-platform helpers (Swift options.with(jsonSchema: T.jsonSchema()),
Kotlin setResponseFormatType<T>()). Fix the streaming-response cell to name
the real Swift type (SkieSwiftFlow<MessageResponse>, iterable with
`for try await`) instead of AsyncThrowingStream. Switch the role-tagged
message example to ChatMessage(role:textContent:) to avoid the 4-arg
content-list form.
Summary
Fixes every Android-SDK doc QA finding from Linear (DOC-27, DOC-37..DOC-60 — 25 tickets, 41 numbered findings) against the v0.10.6 SDK. Every snippet was verified against
leap-android-sdkat commitcac3d06(v0.10.6 publish snapshot). Examples underexamples/android/had the same outdated patterns and are fixed in the same PR.What changed (one commit per page for clean review)
fbb38dbsdk/quick-start.mdxb7dc763sdk/model-loading.mdxd8d825asdk/ai-agent-usage-guide.mdx3770f5csdk/conversation-generation.mdxexportToJSON()return type)7cb0e03sdk/messages-content.mdxd2cb11asdk/constrained-generation.mdx06800f0sdk/voice-assistant.mdx2a3456bsdk/desktop-platforms.mdx2af37d7sdk/utilities.mdx24fe022sdk/advanced-features.mdxbff0d0dsdk/openai-client.mdx972b174examples/android/*.mdxb71e453leap/edge-sdk/overview.mdx/leap/edge-sdk/overviewredirect)863fd87sdk/advanced-features.mdxaudit follow-upJSONSchemaGenerator/GeneratableFactoryreference signatures)63f2040examples/android/vision-language-model-example.mdxaudit follow-upImage(ByteArray)ctor hard-codesdata:image/jpeg;base64,…)455bf7e8b13e7fexamples/android/recipe-generator-constrained-output.mdxaudit follow-upGeneratable/Guidefromai.liquid.leap.structuredoutput, not the root package)Bonus (caught on critical review, not in the QA report)
Three discrepancies surfaced only after re-auditing against the v0.10.6 source — they were not in the original QA list:
Conversation.exportToJSON()returnsString, not[[String: Any]](perleap-sdk/src/appleMain/.../compat/ConversationExtensions.kt:45). Fixed in3770f5c/2af37d7.advanced-features.mdxdocumentedJSONSchemaGenerator.getJSONSchema(klass: KClass<T>)/GeneratableFactory.createFromJSONObject(jsonObject: org.json.JSONObject)— neither overload exists. Real signatures useKSerializer<T>+ reified, andkotlinx.serialization.json.JsonObject. Fixed in863fd87.vision-language-model-example.mdxencoded the bitmap as PNG before passing toChatMessageContent.Image(ByteArray). The convenience secondary ctor hard-codes adata:image/jpeg;base64,…URL prefix, so PNG bytes shipped with a wrong content-type label. Now usesImageUtils.fromBitmap(...)which JPEG-encodes viaBitmap.compress(JPEG, ...). Fixed in63f2040.Note
sdk/function-calling.mdxwas untouched — the QA report (DOC-60) listed it as affected, but after the v0.10.6 multiplatform unification the page no longer contains thesetResponseFormatType(::class)construct and already uses the correctLeapStr/LeapArr/...names.Test plan
npx mintlify devfrom the worktree boots cleanly with no MDX parse errors./deployment/on-device/android/*, 10/deployment/on-device/ios/*, plus:slug*wildcards and theleap/edge-sdk/*paths) return 307 redirects to/deployment/on-device/sdk/*.cac3d06. Post-fix audit performed three times (each pass surfaced new discrepancies, see Bonus).leap-android-sdk@cac3d06per package:leap-sdk,leap-sdk-model-downloader,leap-sdk-openai-client,leap-ui.Refs DOC-27, DOC-37, DOC-38, DOC-39, DOC-40, DOC-41, DOC-42, DOC-43, DOC-44, DOC-45, DOC-46, DOC-47, DOC-48, DOC-49, DOC-50, DOC-51, DOC-52, DOC-53, DOC-54, DOC-55, DOC-56, DOC-57, DOC-58, DOC-59, DOC-60.