
RAG integration and UI components for building retrieval-augmented generation flows, featuring document indexing, local search, embedding support, and chat-style conversational interfaces.
A Kotlin Multiplatform (KMP) library providing RAG (Retrieval-Augmented Generation) integration with a ready-to-use chatbot UI. The library integrates with Flowise as the RAG backend and targets Android, iOS, and Desktop (JVM).
Published to Maven Central as io.github.sjaindl:mobile-rag-assistant.
Add the dependency to your build.gradle.kts:
implementation("io.github.sjaindl:mobile-rag-assistant:1.0.3")Initialize Koin at app startup and provide an AssistantConfig:
startKoin {
modules(assistantModule)
single {
AssistantConfig(
provider = Provider.Flowise(
baseUrl = "https://your-flowise-domain/flowise/api/v1/prediction/<chatflow-id>",
apiKey = "your_api_key", // optional
),
appBarTitle = Res.string.appName,
)
}
}The library provides an assistantGraph extension on NavGraphBuilder and a navigateToAssistant() extension on NavController for integration into your existing Compose Navigation setup:
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomeScreen() }
assistantGraph(rootNavController = navController)
}Navigate to the chat screen from anywhere:
navController.navigateToAssistant()| Parameter | Type | Default | Description |
|---|---|---|---|
provider |
Provider |
required | Backend provider (currently Provider.Flowise) |
appBarTitle |
StringResource |
required | Title shown in the chat app bar |
appBarIcon |
ChatIcon? |
null |
Icon shown in the app bar |
appBarIconTint |
Boolean |
false |
Whether to tint the app bar icon |
streaming |
Boolean |
true |
Enable SSE streaming responses |
streamingDelayMilliseconds |
Long |
4L |
Delay between streamed chunks (ms) |
showTools |
Boolean |
true |
Show tool/agent call info in chat |
showSourceDocuments |
Boolean |
true |
Show source document references |
welcomeMessage |
StringResource? |
null |
Message shown at the start of a new chat |
sampleQuestions |
List<StringResource> |
[] |
Suggested questions displayed to the user |
persistMessages |
Boolean |
true |
Persist messages locally with SQLDelight |
resetOption |
Boolean |
true |
Show reset/clear chat button |
assistantIcon |
ChatIcon |
Chat icon | Icon shown next to assistant messages |
userIcon |
ChatIcon |
Person icon | Icon shown next to user messages |
promptPlaceholder |
StringResource |
"Prompt" |
Placeholder in the message input field |
messageCharLimit |
Int |
250 |
Maximum characters per message |
ChatIcon can be either a Compose ImageVector or a DrawableResource:
ChatIcon.Vector(imageVector = Icons.Default.MyIcon)
ChatIcon.Drawable(drawable = Res.drawable.my_icon)The :assistant module follows clean architecture:
UI Layer → ChatScreen / ChatViewModel (Compose + MVVM, StateFlow)
Domain Layer → Use cases (GetAssistantCompletionUseCase, etc.)
Data Layer → AssistantRepositoryImpl
├─ Remote: KtorAssistantService (Flowise SSE streaming)
└─ Local: ChatMessageDataSource (SQLDelight)
DI → Koin modules (assistantModule, dataModule, domainModule, platformModule)
Platform-specific code (Ktor client engine, SQLDelight driver, Koin platform module) lives in androidMain, iosMain, and jvmMain via Kotlin expect/actual.
androidApp → composeApp → assistant (core library)
iosApp (Xcode) → composeApp (as KMP framework)
| Module | Description |
|---|---|
:assistant |
Publishable library — core logic, Compose UI, use cases, data layer, Koin DI |
:composeApp |
Shared multiplatform app shell — wires AssistantConfig via BuildKonfig |
:androidApp |
Android application entry point (MainActivity) |
iosApp/ |
Xcode project linking the KMP framework from :composeApp
|
| Dependency | Version | Purpose |
|---|---|---|
| Kotlin Multiplatform | 2.3.20 | Multiplatform build |
| Compose Multiplatform | 1.10.3 | Shared UI |
| Ktor | 3.4.2 | HTTP client (SSE streaming to Flowise) |
| SQLDelight | 2.3.2 | Local chat history persistence |
| Koin | 4.2.0 | Dependency injection (multiplatform) |
| Kotlinx Serialization | 1.10.0 | JSON parsing of Flowise responses |
| Napier | 2.7.1 | Multiplatform logging |
| Coil | 3.4.0 | Image loading in Compose |
| BuildKonfig | 6.0.9 | Injects local.properties values into common code |
Create local.properties in the project root:
FLOWISE_API_KEY=your_api_key_here
# For publishing only:
signing.keyId=...
signing.secretSigningKeyFile=path/to/key.gpg
signing.password=...The Flowise backend URL is configured in:
composeApp/src/commonMain/kotlin/com/sjaindl/app/di/KoinInit.ktassistant/src/commonMain/kotlin/com/sjaindl/assistant/config/DOMAIN.kt# Build all modules
./gradlew build
# Run common/JVM tests
./gradlew :assistant:jvmTest
# Run Android host tests
./gradlew :assistant:androidHostTest
# Run a single test class
./gradlew :assistant:jvmTest --tests "com.sjaindl.assistant.TokenizerTest"
# Generate documentation
./gradlew :assistant:dokkaGeneratePublicationHtml
# Publish to Maven Central (requires local.properties signing config)
./gradlew :assistant:publish
# Run the desktop app
./gradlew :composeApp:runThe library is published to Maven Central using the Vanniktech Maven Publish plugin with PGP signing.
io.github.sjaindl
mobile-rag-assistant
assistant/build.gradle.kts
A Kotlin Multiplatform (KMP) library providing RAG (Retrieval-Augmented Generation) integration with a ready-to-use chatbot UI. The library integrates with Flowise as the RAG backend and targets Android, iOS, and Desktop (JVM).
Published to Maven Central as io.github.sjaindl:mobile-rag-assistant.
Add the dependency to your build.gradle.kts:
implementation("io.github.sjaindl:mobile-rag-assistant:1.0.3")Initialize Koin at app startup and provide an AssistantConfig:
startKoin {
modules(assistantModule)
single {
AssistantConfig(
provider = Provider.Flowise(
baseUrl = "https://your-flowise-domain/flowise/api/v1/prediction/<chatflow-id>",
apiKey = "your_api_key", // optional
),
appBarTitle = Res.string.appName,
)
}
}The library provides an assistantGraph extension on NavGraphBuilder and a navigateToAssistant() extension on NavController for integration into your existing Compose Navigation setup:
NavHost(navController = navController, startDestination = "home") {
composable("home") { HomeScreen() }
assistantGraph(rootNavController = navController)
}Navigate to the chat screen from anywhere:
navController.navigateToAssistant()| Parameter | Type | Default | Description |
|---|---|---|---|
provider |
Provider |
required | Backend provider (currently Provider.Flowise) |
appBarTitle |
StringResource |
required | Title shown in the chat app bar |
appBarIcon |
ChatIcon? |
null |
Icon shown in the app bar |
appBarIconTint |
Boolean |
false |
Whether to tint the app bar icon |
streaming |
Boolean |
true |
Enable SSE streaming responses |
streamingDelayMilliseconds |
Long |
4L |
Delay between streamed chunks (ms) |
showTools |
Boolean |
true |
Show tool/agent call info in chat |
showSourceDocuments |
Boolean |
true |
Show source document references |
welcomeMessage |
StringResource? |
null |
Message shown at the start of a new chat |
sampleQuestions |
List<StringResource> |
[] |
Suggested questions displayed to the user |
persistMessages |
Boolean |
true |
Persist messages locally with SQLDelight |
resetOption |
Boolean |
true |
Show reset/clear chat button |
assistantIcon |
ChatIcon |
Chat icon | Icon shown next to assistant messages |
userIcon |
ChatIcon |
Person icon | Icon shown next to user messages |
promptPlaceholder |
StringResource |
"Prompt" |
Placeholder in the message input field |
messageCharLimit |
Int |
250 |
Maximum characters per message |
ChatIcon can be either a Compose ImageVector or a DrawableResource:
ChatIcon.Vector(imageVector = Icons.Default.MyIcon)
ChatIcon.Drawable(drawable = Res.drawable.my_icon)The :assistant module follows clean architecture:
UI Layer → ChatScreen / ChatViewModel (Compose + MVVM, StateFlow)
Domain Layer → Use cases (GetAssistantCompletionUseCase, etc.)
Data Layer → AssistantRepositoryImpl
├─ Remote: KtorAssistantService (Flowise SSE streaming)
└─ Local: ChatMessageDataSource (SQLDelight)
DI → Koin modules (assistantModule, dataModule, domainModule, platformModule)
Platform-specific code (Ktor client engine, SQLDelight driver, Koin platform module) lives in androidMain, iosMain, and jvmMain via Kotlin expect/actual.
androidApp → composeApp → assistant (core library)
iosApp (Xcode) → composeApp (as KMP framework)
| Module | Description |
|---|---|
:assistant |
Publishable library — core logic, Compose UI, use cases, data layer, Koin DI |
:composeApp |
Shared multiplatform app shell — wires AssistantConfig via BuildKonfig |
:androidApp |
Android application entry point (MainActivity) |
iosApp/ |
Xcode project linking the KMP framework from :composeApp
|
| Dependency | Version | Purpose |
|---|---|---|
| Kotlin Multiplatform | 2.3.20 | Multiplatform build |
| Compose Multiplatform | 1.10.3 | Shared UI |
| Ktor | 3.4.2 | HTTP client (SSE streaming to Flowise) |
| SQLDelight | 2.3.2 | Local chat history persistence |
| Koin | 4.2.0 | Dependency injection (multiplatform) |
| Kotlinx Serialization | 1.10.0 | JSON parsing of Flowise responses |
| Napier | 2.7.1 | Multiplatform logging |
| Coil | 3.4.0 | Image loading in Compose |
| BuildKonfig | 6.0.9 | Injects local.properties values into common code |
Create local.properties in the project root:
FLOWISE_API_KEY=your_api_key_here
# For publishing only:
signing.keyId=...
signing.secretSigningKeyFile=path/to/key.gpg
signing.password=...The Flowise backend URL is configured in:
composeApp/src/commonMain/kotlin/com/sjaindl/app/di/KoinInit.ktassistant/src/commonMain/kotlin/com/sjaindl/assistant/config/DOMAIN.kt# Build all modules
./gradlew build
# Run common/JVM tests
./gradlew :assistant:jvmTest
# Run Android host tests
./gradlew :assistant:androidHostTest
# Run a single test class
./gradlew :assistant:jvmTest --tests "com.sjaindl.assistant.TokenizerTest"
# Generate documentation
./gradlew :assistant:dokkaGeneratePublicationHtml
# Publish to Maven Central (requires local.properties signing config)
./gradlew :assistant:publish
# Run the desktop app
./gradlew :composeApp:runThe library is published to Maven Central using the Vanniktech Maven Publish plugin with PGP signing.
io.github.sjaindl
mobile-rag-assistant
assistant/build.gradle.kts