Multi-provider AI chat SDK for Android apps. Add a ready-made Jetpack Compose chat UI or call the same providers from a headless Kotlin API.
The SDK currently supports OpenAI, Gemini, Claude/Anthropic, and Grok/xAI through one configuration surface.
The host Android app integrates the SDK either through the ready-made Compose chat UI or the headless API. Both flows go through the SDK core, which handles configuration, message flow, local history, and provider routing. The provider registry allows the SDK to connect with built-in AI providers or a custom backend.
- Ready-to-use Compose chat screen with message bubbles, loading state, and typing indicator.
- Headless API for apps that need AI responses without the bundled UI.
- Runtime provider switching with OpenAI, Gemini, Claude/Anthropic, and Grok/xAI.
- Room-backed local message history.
- Persona/system prompt support.
- Provider configuration validation before opening chat.
- Sample app for testing provider keys and models.
Add the Maven Central dependency:
implementation("io.github.salmanashraf:aichatlib:1.0.4")Minimum requirements:
- Android 7.0+ / API 24+
- Kotlin 2.0+
- Jetpack Compose for the bundled chat UI
Initialize the SDK once, usually from your Application class:
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
ChatSdk.configure(this) {
defaultProvider = ProviderId.OPEN_AI
openAI(BuildConfig.OPENAI_KEY)
}
}
}Show the chat UI in any Compose screen:
ChatScreen()Use the headless API when you do not want the bundled UI:
val reply = ChatSdk.client().respond(
prompt = "Write a short welcome message for my app."
)ChatSdk.configure(applicationContext) {
defaultProvider = ProviderId.OPEN_AI
openAI(
apiKey = BuildConfig.OPENAI_KEY,
model = "gpt-4.1"
)
}Use an API key:
ChatSdk.configure(applicationContext) {
defaultProvider = ProviderId.GEMINI
gemini(
apiKey = BuildConfig.GEMINI_KEY,
model = "models/gemini-2.5-flash"
)
}Or pass a google.json string:
ChatSdk.configure(applicationContext) {
defaultProvider = ProviderId.GEMINI
geminiServiceJson(
json = googleJson,
model = "models/gemini-2.5-flash"
)
}ChatSdk.configure(applicationContext) {
defaultProvider = ProviderId.ANTHROPIC
anthropic(
apiKey = BuildConfig.ANTHROPIC_KEY,
model = "claude-sonnet-4-20250514"
)
}ChatSdk.configure(applicationContext) {
defaultProvider = ProviderId.XAI
xAI(
apiKey = BuildConfig.XAI_KEY,
model = "grok-4.3"
)
}If users enter provider keys inside your app, validate the active provider before opening chat:
val validation = ChatSdk.config().validateDefaultProvider()
if (!validation.isValid) {
showError(validation.errors.joinToString("\n"))
}For fail-fast setup:
ChatSdk.config().requireValidDefaultProvider()ChatSdk.applyConfig(
ChatSdkConfig(
defaultProvider = ProviderId.GEMINI,
credentials = mapOf(
ProviderId.GEMINI to ProviderCredential.ApiKey(BuildConfig.GEMINI_KEY)
),
providerModels = mapOf(
ProviderId.GEMINI to "models/gemini-2.5-flash"
)
)
)Use a persona/system prompt with the bundled UI:
ChatScreen(
personaPrompt = "You are a concise support assistant.",
usePersona = true
)Use a persona prompt with the headless API:
val reply = ChatSdk.client().respond(
prompt = "Explain this error to a beginner.",
personaPrompt = "You are a patient Android mentor.",
usePersona = true
)Do not ship unrestricted provider API keys inside a production APK or app bundle.
Direct API key configuration is useful for demos, internal tools, and local validation. Production apps should call your own backend. The backend should own provider credentials, authenticate users, enforce rate limits, and return only the model response to the mobile app.
See docs/security.md for the recommended backend-provider pattern.
Initialize the SDK before calling ChatScreen() or ChatSdk.client():
ChatSdk.configure(applicationContext) {
defaultProvider = ProviderId.OPEN_AI
openAI(BuildConfig.OPENAI_KEY)
}The selected provider does not have a registered engine. Use ChatSdk.configure(...), ChatSdk.initializeWithDefaults(...), or register a custom LLMEngine.
Call validateDefaultProvider() and show validation.errors to the user before opening chat.
The JSON must include either api_key or apiKey. The sample app reads sampleapp/src/main/assets/google.json automatically when Gemini is selected.
Confirm Maven Central is enabled:
repositories {
mavenCentral()
}The sampleapp module demonstrates:
- Provider selection.
- Model selection.
- API key entry.
- Gemini
google.jsonloading. - Compose chat UI.
- Headless prompt testing.
Run it from Android Studio with the sampleapp configuration.
| Module | Description |
|---|---|
ai-chat-lib |
Published Android library with SDK core, provider engines, Compose UI, and Room persistence. |
sampleapp |
Demo app for manual testing and provider switching. |
docs |
Integration, security, roadmap, testing, and publishing docs. |
- High-level architecture
- Getting started
- Security guide
- Development test guide
- Publishing guide
- Provider roadmap
- The bundled UI is Compose-first.
- Production apps should use a backend proxy instead of direct mobile provider keys.
- Streaming responses are not yet shipped.
- Advanced tools, RAG, and embeddings are roadmap items.
