Package-level declarations

Types

Link copied to clipboard
data class AiCapabilities(val streaming: Boolean, val multimodal: Boolean, val honoredConfigFields: Set<String>, val unavailableReason: AiFailure?)

Honest, machine-readable answer to "what can this AI backend actually do right now" — the counterpart to a bare isAvailable(): Boolean that collapses "streams tokens", "accepts images" and "why is this off" into a single true/false a caller can't act on or show to a user. Lives in :result next to AiFailure for the same reason: the on-device (:ai) and cloud (:llm-chat) seams both report through it rather than inventing their own descriptor shape.

Link copied to clipboard
enum class AiFailure : Enum<AiFailure>

Why an AI call (com.siddharth.kmp.llmchat.AiProvider.complete or on-device OnDeviceLlm.generate) didn't produce text. Lives in :result — a zero-dependency module both the cloud (:llm-chat) and on-device (:ai) seams already sit downstream of conceptually — so neither invents its own error type and callers handling both seams share one when.

Link copied to clipboard
typealias AiResult<T> = Result<T, AiFailure>

Success-or-typed-failure for an AI call: the model's text, or the AiFailure naming why not.

Link copied to clipboard
sealed interface DataError

Root of the typed error hierarchy carried in Result.Failure. Split by source so callers can react differently to a network failure vs a local one. Apps extend this with their own arms (e.g. a Validation error) by implementing the interface.

Link copied to clipboard
typealias EmptyResult<E> = Result<Unit, E>

A Result carrying no success payload — for operations whose success is just "it worked".

Link copied to clipboard

One prompt-injection guard reused at both AI seams — on-device (:ai's CompositeOnDeviceLlm) and cloud (:llm-chat's buildProviderChain) — so a receipt, job description, or chat message that says "ignore previous instructions" is treated as inert data by every app in the family, not just the careful ones. Lives in :result, not either seam module: :ai has no wasmJs target but :llm-chat does, so a shared helper has to sit somewhere both already depend on — same reason AiResult/AiFailure live here instead of being duplicated per seam.

Link copied to clipboard
sealed interface Result<out D, out E>

A typed success-or-failure. Unlike kotlin.Result, the error arm is a typed E (usually a DataError) rather than a Throwable, so callers exhaustively handle known failure modes instead of catching. Import this Result explicitly where kotlin.Result is also in scope.

Functions

Link copied to clipboard
fun <D, E> Result<D, E>.asEmpty(): EmptyResult<E>

Discard the success payload, keeping only success-vs-failure.

Link copied to clipboard
fun <D, E> Result<D, E>.errorOrNull(): E?
Link copied to clipboard
inline fun <D, E, R> Result<D, E>.flatMap(transform: (D) -> Result<R, E>): Result<R, E>

Chain a success into another Result; failures short-circuit.

Link copied to clipboard
inline fun <D, E, R> Result<D, E>.fold(onSuccess: (D) -> R, onFailure: (E) -> R): R

Collapse both arms into one value.

Link copied to clipboard
fun <D, E> Result<D, E>.getOrNull(): D?
Link copied to clipboard
inline fun <D, E, R> Result<D, E>.map(transform: (D) -> R): Result<R, E>

Map the success value; failures pass through untouched.

Link copied to clipboard
inline fun <D, E, F> Result<D, E>.mapError(transform: (E) -> F): Result<D, F>

Map the error arm; successes pass through untouched.

Link copied to clipboard
inline fun <D, E> Result<D, E>.onFailure(action: (E) -> Unit): Result<D, E>

Run action on failure, returning the receiver for chaining.

Link copied to clipboard
inline fun <D, E> Result<D, E>.onSuccess(action: (D) -> Unit): Result<D, E>

Run action on success, returning the receiver for chaining.