Skip to main content
LeapOpenAIClient / leap-openai-client (introduced in v0.10.0) 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 SDK release as LeapSDK, so you can route requests between an on-device LFM and a cloud model from a single app.

When to use it

  • Hybrid on-device + cloud routing. Run small / fast models on-device with LeapSDK, fall back to a larger cloud model for hard prompts.
  • Standardised cloud API. Talk to any OpenAI-compatible backend without pulling in a heavier OpenAI SDK.
  • Streaming first. SSE streaming is the only mode β€” non-streaming requests aren’t exposed. streamChatCompletion(...) forces stream = true on the outgoing request regardless of the stream field on the ChatCompletionRequest you pass in.

Add the dependency

Add the LeapOpenAIClient product to your target. See the Quick Start for the full SPM setup.
In Swift sources, import LeapOpenAIClient. The Darwin (URLSession) Ktor engine is bundled β€” no extra HTTP setup needed.

Basic usage

The leap-sdk-openai-client Kotlin module does not apply the SKIE plugin in v0.10.7 (only leap-sdk, leap-sdk-model-downloader, and leap-ui do). That means Flow<ChatCompletionEvent> is not bridged to a Swift AsyncSequence and the onEnum(of:) helper is not generated for ChatCompletionEvent. Swift consumers on v0.10.7 must collect the Kotlin Flow through its native collector and downcast each event with as?. For most Swift apps that just need cloud chat completions, an off-the-shelf OpenAI Swift client is more ergonomic β€” use LeapOpenAIClient from Swift only if you need to share Kotlin code with Android.Coming in the next release: SKIE will be enabled on leap-sdk-openai-client, adding the same Swift-friendly surface as LeapSDK β€” for try await event in client.streamChatCompletion(...), onEnum(of: event) exhaustive switching, and nested-class Swift names (ChatCompletionEvent.Delta instead of the current flattened ChatCompletionEventDelta). Swift convenience inits and builders for OpenAiClientConfig are also planned. Pin to v0.10.7 if you need the current behavior frozen; otherwise expect the more ergonomic surface to land soon.
Manual collection pattern (the Flow<ChatCompletionEvent>.collect(...) shape varies by Kotlin/Native version β€” check the framework header in your Xcode build for the exact label):

Configuration

OpenAiClientConfig is a Kotlin data class bridged identically on every platform.

OpenRouter

Self-hosted vLLM / llama-server

Request shape

ChatCompletionRequest covers standard OpenAI fields plus a few OpenRouter-specific extensions. OpenRouter-only fields are silently ignored by stock OpenAI-compatible APIs.
ChatMessage (the OpenAI-client one, distinct from LeapSDK.ChatMessage) is a sealed type with three cases β€” System, User, Assistant.

Response shape

streamChatCompletion(request) returns a Flow<ChatCompletionEvent> (Kotlin) β€” and the same Flow is exposed verbatim to Swift in v0.10.7 (no SKIE on this module yet, so it’s not bridged to a Swift AsyncSequence; collect it via the native Flow.collect(...) shape shown above). Events:

Hybrid routing example

Route simple prompts to a small on-device LFM; escalate harder prompts to a cloud model.
See Cloud AI Comparison for a side-by-side feature breakdown.

Lifecycle

The platform OpenAiClient(config:) factory (Kotlin fun OpenAiClient(config:) β†’ Swift OpenAiClientKt.OpenAiClient(config:)) creates an HttpClient internally and ties it to the returned client β€” call close() when you’re done.
The lower-level constructor that accepts an externally-managed HttpClient is part of the Kotlin/Ktor surface and isn’t a useful entry point from Swift β€” the Ktor engine machinery isn’t bridged into the public Swift API. Use OpenAiClientKt.OpenAiClient(config:) and let the SDK own the session. If multiple consumers share a client, share the OpenAiClient instance and close() once at teardown.