
Client for interacting with app API: request/response handling with JSON, file and form inputs, collection-format queries (csv/tsv/ssv/pipes), numerous domain models (payments, chat, AI) and bearer auth.
A multiplatform Kotlin library providing access to various AI models (image generation, text chat, audio transcription) via a unified API. The library abstracts the underlying implementation details, allowing the same Kotlin code to run on Android (via JNI to Rust) and Web (via WebAssembly).
expect/actual pattern hides platform-specific FFI details.zImageTurbo, nanoBanana2, flux2Pro, flux2DevI2I, flux2KleinI2I.ltx2_3a2v (Image + Audio to Video).qwen3_6_35b_a3b (Qwen 3.6 35B A3B).qwen3AsrFlash (ASR Flash).The project uses Kotlin Multiplatform (KMP) to share business logic while delegating native interactions to platform-specific implementations.
kotlinapi/src/commonMain/: Contains the shared API definitions (expect functions) and data classes.kotlinapi/src/androidMain/: Android-specific implementation using JNI to call a Rust library (rust_ffi).kotlinapi/src/webMain/: Web-specific implementation using Kotlin/JS interop to call a WebAssembly module (rust_ffi).webDemo/: A demo application running in the browser to showcase functionality.kotlinapi/src/commonMain/kotlin/market/femi/kotlinapi/:
ZImageTurbo.kt, NanoBanana2.kt, Flux2Pro.kt, etc.: Define the expect suspend functions.Qwen3_6_35b_a3b.kt: Defines ChatMessage and Role data classes used for chat interactions.Qwen3AsrFlash.kt: Defines the audio transcription interface.kotlinapi/src/androidMain/kotlin/market/femi/kotlinapi/:
FemiApiJvm.kt: Declares external functions that map to the native Rust library.CancelFlag.kt: Implements cancellation logic for Android by passing a pointer to a native byte buffer. If the coroutine is cancelled, the byte is flipped to signal the native code to abort.*.kt files (e.g., ZImageTurbo.kt): Implement the actual functions, wrapping the JNI calls with cancellation support.kotlinapi/src/webMain/kotlin/market/femi/kotlinapi/:
RustFfi.kt: Declares the WebAssembly module interface using @JsModule("rust_ffi").*.kt files: Implement the actual functions, awaiting Promises from the WASM module and converting results to Kotlin types.webDemo/src/wasmJsMain/kotlin/Main.kt:
Include the library in your build.gradle.kts (or build.gradle) for the common module:
dependencies {
implementation("market.femi:kotlinapi:1.0.0") // Replace with actual version
}For Android, ensure you have the necessary NDK setup. For Web, ensure your build system supports Kotlin/JS with Wasm.
Generate an image from a text prompt:
import market.femi.kotlinapi.zImageTurbo
val user = "your_username"
val pass = "your_password"
val prompt = "a futuristic city at sunset"
val imageBytes = zImageTurbo(user, pass, prompt)
// imageBytes contains the raw image data (PNG/JPEG)Transform an existing image:
import market.femi.kotlinapi.flux2DevI2I
val imageB64 = "base64_encoded_image_string"
val prompt = "make it cyberpunk"
val resultBytes = flux2DevI2I(user, pass, imageB64, prompt)Interact with the Qwen model:
import market.femi.kotlinapi.qwen3_6_35b_a3b
import market.femi.kotlinapi.ChatMessage
import market.femi.kotlinapi.Role
val messages = listOf(
ChatMessage(Role.User, "Hello, how are you?")
)
val response = qwen3_6_35b_a3b(user, pass, messages)
val lastReply = response.lastOrNull()?.contentTranscribe audio data:
import market.femi.kotlinapi.qwen3AsrFlash
val audioData: ByteArray = /* your audio bytes */
val transcript = qwen3AsrFlash(user, pass, audioData)librust_ffi.so) is built for Android targets (arm64-v8a, armeabi-v7a, x86_64).System.loadLibrary("rust_ffi") in FemiApiJvm.kt../gradlew :kotlinapi:assembleReleaseRustFfi.kt../gradlew :kotlinapi:wasmJsBrowserDistributionTo run the web demo:
./gradlew :webDemo:wasmJsBrowserRunOn Android, long-running native calls can be cancelled by cancelling the coroutine. This is implemented in CancelFlag.kt by passing a pointer to a native byte buffer. If the coroutine is cancelled, the byte is set to 1, signaling the native Rust code to abort the operation early.
On Web, cancellation is handled by the JavaScript runtime and the WASM module's promise resolution.
qwen3AsrFlash which takes raw ByteArray (and encodes it internally).ChatMessage class uses Role enum with @SerialName annotations to match the wire format expected by the backend."Could not respond".user and pass string. In production, these should be handled securely. The demo auto-funds new users with 50 credits.A multiplatform Kotlin library providing access to various AI models (image generation, text chat, audio transcription) via a unified API. The library abstracts the underlying implementation details, allowing the same Kotlin code to run on Android (via JNI to Rust) and Web (via WebAssembly).
expect/actual pattern hides platform-specific FFI details.zImageTurbo, nanoBanana2, flux2Pro, flux2DevI2I, flux2KleinI2I.ltx2_3a2v (Image + Audio to Video).qwen3_6_35b_a3b (Qwen 3.6 35B A3B).qwen3AsrFlash (ASR Flash).The project uses Kotlin Multiplatform (KMP) to share business logic while delegating native interactions to platform-specific implementations.
kotlinapi/src/commonMain/: Contains the shared API definitions (expect functions) and data classes.kotlinapi/src/androidMain/: Android-specific implementation using JNI to call a Rust library (rust_ffi).kotlinapi/src/webMain/: Web-specific implementation using Kotlin/JS interop to call a WebAssembly module (rust_ffi).webDemo/: A demo application running in the browser to showcase functionality.kotlinapi/src/commonMain/kotlin/market/femi/kotlinapi/:
ZImageTurbo.kt, NanoBanana2.kt, Flux2Pro.kt, etc.: Define the expect suspend functions.Qwen3_6_35b_a3b.kt: Defines ChatMessage and Role data classes used for chat interactions.Qwen3AsrFlash.kt: Defines the audio transcription interface.kotlinapi/src/androidMain/kotlin/market/femi/kotlinapi/:
FemiApiJvm.kt: Declares external functions that map to the native Rust library.CancelFlag.kt: Implements cancellation logic for Android by passing a pointer to a native byte buffer. If the coroutine is cancelled, the byte is flipped to signal the native code to abort.*.kt files (e.g., ZImageTurbo.kt): Implement the actual functions, wrapping the JNI calls with cancellation support.kotlinapi/src/webMain/kotlin/market/femi/kotlinapi/:
RustFfi.kt: Declares the WebAssembly module interface using @JsModule("rust_ffi").*.kt files: Implement the actual functions, awaiting Promises from the WASM module and converting results to Kotlin types.webDemo/src/wasmJsMain/kotlin/Main.kt:
Include the library in your build.gradle.kts (or build.gradle) for the common module:
dependencies {
implementation("market.femi:kotlinapi:1.0.0") // Replace with actual version
}For Android, ensure you have the necessary NDK setup. For Web, ensure your build system supports Kotlin/JS with Wasm.
Generate an image from a text prompt:
import market.femi.kotlinapi.zImageTurbo
val user = "your_username"
val pass = "your_password"
val prompt = "a futuristic city at sunset"
val imageBytes = zImageTurbo(user, pass, prompt)
// imageBytes contains the raw image data (PNG/JPEG)Transform an existing image:
import market.femi.kotlinapi.flux2DevI2I
val imageB64 = "base64_encoded_image_string"
val prompt = "make it cyberpunk"
val resultBytes = flux2DevI2I(user, pass, imageB64, prompt)Interact with the Qwen model:
import market.femi.kotlinapi.qwen3_6_35b_a3b
import market.femi.kotlinapi.ChatMessage
import market.femi.kotlinapi.Role
val messages = listOf(
ChatMessage(Role.User, "Hello, how are you?")
)
val response = qwen3_6_35b_a3b(user, pass, messages)
val lastReply = response.lastOrNull()?.contentTranscribe audio data:
import market.femi.kotlinapi.qwen3AsrFlash
val audioData: ByteArray = /* your audio bytes */
val transcript = qwen3AsrFlash(user, pass, audioData)librust_ffi.so) is built for Android targets (arm64-v8a, armeabi-v7a, x86_64).System.loadLibrary("rust_ffi") in FemiApiJvm.kt../gradlew :kotlinapi:assembleReleaseRustFfi.kt../gradlew :kotlinapi:wasmJsBrowserDistributionTo run the web demo:
./gradlew :webDemo:wasmJsBrowserRunOn Android, long-running native calls can be cancelled by cancelling the coroutine. This is implemented in CancelFlag.kt by passing a pointer to a native byte buffer. If the coroutine is cancelled, the byte is set to 1, signaling the native Rust code to abort the operation early.
On Web, cancellation is handled by the JavaScript runtime and the WASM module's promise resolution.
qwen3AsrFlash which takes raw ByteArray (and encodes it internally).ChatMessage class uses Role enum with @SerialName annotations to match the wire format expected by the backend."Could not respond".user and pass string. In production, these should be handled securely. The demo auto-funds new users with 50 credits.