Skip to content

feat(ai): massive architecture overhaul, new providers, and generation tuning#2371

Open
VoidX3D wants to merge 30 commits into
PixelPlayerHQ:masterfrom
VoidX3D:master
Open

feat(ai): massive architecture overhaul, new providers, and generation tuning#2371
VoidX3D wants to merge 30 commits into
PixelPlayerHQ:masterfrom
VoidX3D:master

Conversation

@VoidX3D

@VoidX3D VoidX3D commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Overview

Removes the unused AiMetadataGenerator feature, adds generation parameters (temperature, topP, topK, maxTokens, presence/frequency penalty) and song data configuration to the AI settings UI, adds OLLAMA and CUSTOM provider support, overhauls all AI prompts with chain-of-thought reasoning and few-shot examples, and fixes two CI compilation errors.


Breaking Changes

  • AiMetadataGenerator deleted — the AI metadata enhancement feature is removed entirely. All 25+ call sites across screens, holders, and view models have been stripped.

What's New

AI Provider Support

  • OLLAMA provider — added to AiProvider enum, AiClientFactory, provider fallback chain, preferences, and settings UI
  • CUSTOM provider — allows connecting to any OpenAI-compatible endpoint via configurable base URL
  • SearchableModelSelector composable — searchable model dropdown for providers with dynamic model lists
  • Base URL configuration — text field for custom base URLs (visible for OLLAMA and CUSTOM providers)

AI Settings UI

  • Generation Parameters section — sliders/fields for temperature, topP, topK, maxTokens, presence penalty, frequency penalty
  • Song Data Configuration section — sample size selector (10–120), digest mode toggle (safe/full), extended fields toggle
  • All persisted globally (not per-provider) via DataStore prefs

Generation Parameters (Client API)

  • Added topP, topK, maxTokens, presencePenalty, frequencyPenalty to:
    • AiClient interface
    • GenericOpenAiClient.ChatRequest (serialized to JSON)
    • GeminiAiClient.GenerationConfig (serialized to JSON)
  • AiHandler fetches gen params from preferences and passes them through to generateWithRecovery
  • Usage tracking records actual model name (result.modelUsed) instead of provider name

Prompt Engineering

  • AiSystemPromptEngine overhauled with:
    • Chain-of-thought reasoning instructions per type (GENERAL, PLAYLIST, METADATA, DIGEST, CHAT)
    • Few-shot examples for playlist, metadata, and digest generation
    • Quality guardrails (no markdown fences, no preamble, raw JSON only)
    • Self-verification instructions
  • translateLyrics prompt restructured with XML-bounded <task>, <rules>, <format>, <lyrics> sections
  • AiResponseCleaner utility added for robust JSON/text response cleaning (strip markdown fences, trim whitespace, normalize newlines)
  • AiPlaylistGenerator and UserProfileDigestGenerator updated to use AiResponseCleaner

What's Removed

  • DeepSeekAiClient.kt, GroqAiClient.kt, MistralAiClient.kt — unified into GenericOpenAiClient (these are all OpenAI-compatible APIs with identical request/response shapes)
  • AiMetadataGenerator.kt — full file deletion
  • All generateAiMetadata calls removed from: AiStateHolder, PlayerViewModel, PlayerUiState, SongInfoBottomSheet, DailyMixSection, UnifiedPlayerOverlaysLayer, DailyMixScreen, AlbumDetailScreen, ArtistDetailScreen, GenreDetailScreen, LibraryScreen, PlaylistDetailScreen, RecentlyPlayedScreen, SearchScreen, PlayerViewModelTest

Bug Fixes

  • AiHandler.kt — local function callWithModel not marked suspend (CI compilation error)
  • SettingsCategoryScreen.ktcustomBaseUrl StateFlow passed where String expected; now collected via collectAsStateWithLifecycle()
  • GeminiAiClient — removed encodeDefaults = true from Json config to prevent serializing null fields
  • AiWorker — digest generator now uses AiResponseCleaner for robust parsing

Files Changed (37 files, +1054 / −1016)

Added

File Description
data/ai/AiResponseCleaner.kt Response clean/parse utility
data/ai/provider/UnifiedModelFilter.kt Consistent model filtering across providers
presentation/screens/SettingsComponents.kt SearchableModelSelector composable

Deleted

File Description
data/ai/AiMetadataGenerator.kt Metadata generation feature
data/ai/provider/DeepSeekAiClient.kt Unified into GenericOpenAiClient
data/ai/provider/GroqAiClient.kt Unified into GenericOpenAiClient
data/ai/provider/MistralAiClient.kt Unified into GenericOpenAiClient

Modified (key files)

File Key Changes
data/ai/AiHandler.kt Fix suspend, gen params passthrough, usage tracking
data/ai/AiSystemPromptEngine.kt CoT, few-shot, quality rails
data/ai/AiPlaylistGenerator.kt Use AiResponseCleaner
data/ai/UserProfileDigestGenerator.kt Use AiResponseCleaner
data/ai/provider/AiClient.kt +6 gen param interface methods
data/ai/provider/AiClientFactory.kt OLLAMA + CUSTOM creation
data/ai/provider/AiProvider.kt OLLAMA + CUSTOM enum entries
data/ai/provider/GeminiAiClient.kt Gen params, fix Json config
data/ai/provider/GenericOpenAiClient.kt Gen params in request
data/preferences/AiPreferencesRepository.kt +10 new preference keys
data/worker/AiWorker.kt AiResponseCleaner usage
presentation/screens/SettingsCategoryScreen.kt Gen params, song config, base URL sections; fix customBaseUrl
presentation/viewmodel/SettingsViewModel.kt +10 new flows/handlers
presentation/viewmodel/AiStateHolder.kt Remove metadata, improve translate prompt
presentation/viewmodel/PlayerViewModel.kt Remove metadata
presentation/viewmodel/PlayerUiState.kt Remove metadata state
presentation/components/SongInfoBottomSheet.kt Remove metadata
10 screen/component files Remove generateAiMetadata calls
presentation/viewmodel/PlayerViewModelTest.kt Remove metadata test refs

Testing

  • PlayerViewModelTest.kt updated — metadata test references removed
  • All changes are source-level only; existing behavior preserved for remaining AI features (playlist generation, lyrics translation, digest generation)

VoidX3D added 28 commits June 15, 2026 19:06
Renamed the central AI orchestration class from AiOrchestrator to AiHandler
and updated all references across the codebase.
…s all providers

- Create UnifiedModelFilter utility that filters out embedding, image, TTS,
  speech, moderation, vision-only, and other non-chat models
- Update GeminiAiClient to use UnifiedModelFilter instead of hardcoded markers
- Update GenericOpenAiClient to use UnifiedModelFilter instead of inline filter
These providers all use OpenAI-compatible APIs. Switching from dedicated
client classes to GenericOpenAiClient eliminates duplicate code. The old
class files are kept on disk but no longer referenced.
Add CUSTOM provider with hasConfigurableUrl=true and requiresApiKey=true
for user-configured self-hosted/custom API endpoints.
CUSTOM provider uses GenericOpenAiClient with an empty default URL (user
configures it via settings). createClientWithUrl allows creating a client
with a custom base URL for configurable-URL providers.
…ncesRepository

Add getBaseUrl/setBaseUrl generic accessors for configurable-URL providers.
Add customApiKey, customModel, customSystemPrompt, customBaseUrl convenience
flows for the CUSTOM provider.
Ollama is a cloud API-based provider (requires API key, fixed URL),
separate from the CUSTOM provider which allows custom endpoints.
A new composable that opens a ModalBottomSheet with a searchable LazyColumn
of AI models. Includes search filtering, model count display, and visual
selection state.
…ences

Adds DataStore-backed preferences for temperature, topP, topK,
maxTokens, presencePenalty, frequencyPenalty, sample size, digest
mode (safe/full), and extended fields toggle.
- Move provider val to AI_INTEGRATION scope for accessibility
- Remove duplicate base URL AiApiKeyItem block
- Add missing imports: CircleShape, ModalBottomSheet, IconButton,
  OutlinedTextFieldDefaults, GeminiModel, Search, Clear, CheckCircle
… response parsing

- Add AiResponseCleaner utility for cleaning JSON/text AI responses
- Fix usage tracking to record actual model name instead of provider enum
- Update AiPlaylistGenerator and AiMetadataGenerator to use cleaner
- Delete AiMetadataGenerator.kt (AI metadata generation feature)
- Remove all references from AiStateHolder, PlayerViewModel, PlayerUiState
- Remove generateAiMetadata callback from SongInfoBottomSheet
- Strip calls from 10+ screens
- Fix AiHandler callWithModel suspend modifier
- Fix SettingsCategoryScreen customBaseUrl StateFlow to String
- Remove encodeDefaults from GeminiAiClient Json config
- Restructure prompt with <task>, <rules>, <format>, <lyrics> sections
- Clarify timestamp preservation and ALREADY_IN_TARGET_LANGUAGE behavior
- Add AiUiSnapshot data class (showAiPlaylistSheet, isGeneratingAiPlaylist, aiStatus, aiError)
- Re-add combine in PlayerViewModel init to collect AiStateHolder flows into PlayerUiState
- Add showAiPlaylistSheet, isGeneratingAiPlaylist, aiStatus, aiError fields to PlayerUiState
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant