feat: llm switch and multiple ai provider configs - #22
Merged
Conversation
… tracking
This commit performs a major refactor of the settings and history persistence layers, moving from a single JSON-based DataStore to a hybrid approach using Typed DataStore (ProtoBuf) for general preferences and Room for encrypted provider configurations.
### Build & Dependencies
- Bumped `androidx.compose.material3` to `1.5.0-alpha25`.
- Bumped `io.ktor:ktor-client-android` to `3.5.2`.
- Added `androidx.datastore:datastore` and `kotlinx-serialization-protobuf`.
### Data & Persistence
- **Storage Migration**: Migrated `UserPreferences` from `PreferencesDataStore` (JSON) to Typed `DataStore` using ProtoBuf for better performance and type safety.
- **Room Database (v2)**:
- Added `AIProviderConfigEntity` to store provider-specific settings (API keys, base URLs, models) in SQL.
- Added a migration (1 -> 2) to create the `ai_provider_config` table and add `provider`/`model` columns to the history table.
- **Security**: Introduced `SecurityUtil` using Android KeyStore (AES/GCM) to encrypt and decrypt API keys before persisting them to the database.
- **Legacy Migration**: Implemented logic in `AppViewModel` to transparently migrate existing settings from the old DataStore to the new schema.
### UI Components
- **ProviderIndicator**: Added a new reusable component to display the AI provider icon and a short model name badge.
- **Summary Tracking**: Summaries now display which AI provider and model were used to generate them in both the `HomeScreen` and `HistoryScreen`.
- **UI Improvements**:
- Updated `SwipeToDismissBox` usage to align with newer Material3 APIs.
- Refactored the provider selection bottom sheet to gray out unconfigured providers and provide feedback via Toast.
- Improved `SummaryCard` layout to accommodate provider information.
### Logic
- Refactored `AppViewModel` to use a `combine` flow, merging general preferences from DataStore with configuration entities from Room.
- Updated `SummaryViewModel` to persist the specific provider and model used when saving a summary to history.
- Simplified `UserPreferencesRepository` by removing provider-specific configuration logic, now handled by `AIProviderConfigDao`.
This commit updates build dependencies and removes deprecated migration code for legacy user preferences. ### Build & Dependencies - Kotlin version updated to `2.4.0` (plugin `2.4.10`). - Android Gradle Plugin bumped to `9.3.1`. - KSP updated to `2.3.11`. - `minSdk` lowered from `35` to `33`. - Updated Kotlin `languageVersion` to `2.4` and `jvmTarget` to `JVM_25`. ### Refactor - Removed legacy data migration logic from `AppViewModel` and `UserPreferencesRepository`. - Deleted `LegacyUserPreferences` data class and associated migration methods. - Removed `hasMigratedFromLegacy` flag from `UserPreferences` model. - Cleaned up unused imports in `UserPreferencesRepository`. ### Documentation - Updated `AGENTS.md` with new dependency versions and added a code style rule to prefer import statements over fully qualified class names. - Deleted `GEMINI.md`.
This commit refactors the AI provider configuration to be optional by default and enhances the user interface for selecting providers and models.
### Preferences & State
- Updated `UserPreferencesRepository` and `SettingsUiState` to allow `aiProvider` to be null.
- Modified `AppViewModel` to handle nullable providers and added safety checks when updating API keys, base URLs, or models.
- Defaulted provider settings dialogs to `OPENAI` if no provider is currently selected.
### AI & Summarization Logic
- Added validation in `SummaryViewModel` to throw a `NoKeyException` if no AI provider is configured before summarization.
- Introduced support for "Custom" models in the selection UI when a manually entered model ID does not match predefined options.
- Updated history logging to store provider names as strings.
### UI Components
- **HomeScreen**:
- Reorganized `TopAppBar` to group the settings icon and provider indicator.
- Updated provider selection list to sort configured providers (with API keys or base URLs) to the top.
- **ProviderIndicator**:
- Added a fallback `SmartToy` icon for unselected providers.
- Improved model name display with support for up to two lines, text wrapping, and constrained width.
- **Settings**:
- Improved provider and model selection dialogs to handle null states gracefully.
- Added `statusBarsPadding()` to the main onboarding container. - Added `navigationBarsPadding()` to the bottom action row to ensure proper spacing from system navigation.
This commit upgrades the unit testing framework to JUnit 5 and corrects metadata in the documentation. ### Build & Testing - Migrated unit tests from JUnit 4 to JUnit 5 (v6.1.3). - Configured Gradle to use the JUnit Platform for unit tests. - Updated `ExampleUnitTest` to use JUnit Jupiter assertions and annotations. - Added `junit-platform-launcher` for test execution support. ### Documentation - Updated "Minimal Android version" from 15 to 13 in `README.md`. - Fixed capitalization for "GitHub" and "ChatGPT" throughout the README.
This commit enhances the robustness of data persistence and optimizes the security infrastructure. ### Serialization & Data - **UserPreferencesSerializer**: Now performs write operations on `Dispatchers.IO`. - **UserPreferencesSerializer**: Replaced silent error recovery with `CorruptionException` when decoding fails. - Cleaned up code by replacing fully qualified names with imports in `AIProviderConfigEntity`, `AppModule`, `HomeScreen`, and `SettingsScreen`. ### Security - **SecurityUtil**: Implemented `SecretKey` caching to reduce Keystore access overhead. - **SecurityUtil**: Introduced constants for `IV_SIZE` (12) and `TAG_SIZE` (128) to replace magic numbers. - **SecurityUtil**: Improved error handling by using `Log.e` instead of `printStackTrace` and returning empty strings on failure to ensure consistent state.
### UI & Components - Replaced the monolithic `ProviderIndicator` with two specialized components: `LlmSwitcher` (interactive) and `LlmIndicator` (read-only). - Refactored internal display logic into private `ProviderIcon` and `ModelLabel` helper functions for better maintainability. - Updated `ModelLabel` shortening logic to include `mistral` in the list of prefixes to be stripped. - Migrated `SummaryCard` to use `LlmIndicator` and `HomeScreen` to use `LlmSwitcher`. - Refined the layout of model labels, including improved positioning logic based on box size.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat: llm quick switch and indicator
feat: multiple ai provider configs
chore: bump dependencies