Skip to content

feat: enhance AI settings management with local model support and error handling#2142

Closed
VoidX3D wants to merge 126 commits into
PixelPlayerHQ:masterfrom
VoidX3D:master
Closed

feat: enhance AI settings management with local model support and error handling#2142
VoidX3D wants to merge 126 commits into
PixelPlayerHQ:masterfrom
VoidX3D:master

Conversation

@VoidX3D

@VoidX3D VoidX3D commented May 28, 2026

Copy link
Copy Markdown
Contributor

PixelPlayer AI System

Overview

Complete AI infrastructure for PixelPlayer — multi-provider cloud inference, on-device local models with download management, usage analytics, and a dedicated settings UI.

~4,500 lines of new code, ~1,900 lines removed through refactoring.


Cloud Provider System

11 providers supported through a unified client interface:

Client Providers
GenericOpenAiClient DeepSeek, Groq, Mistral, NVIDIA, Kimi, GLM, OpenAI, OpenRouter, Ollama — all via OpenAI-compatible /v1/chat/completions
GeminiAiClient Google Gemini (dedicated REST API)
AnthropicAiClient Claude (Messages API)

Architecture Components

Component Responsibility
AiClientFactory Single creation point; no other class instantiates clients directly
AiProviderEndpoints Every base URL and default model in one file
AiProviderSupport Error classification (isRateLimit, isBillingIssue, isApiKeyIssue), provider fallback chain, request wrapping
AiHandler Main orchestration layer
AiSettingsManager Reactive settings via suspend fun set(block:) — replaced 20 individual setters
API key validation Lightweight chat ping (1 token) instead of /v1/models

Refactoring Highlights

  • 5 provider-specific client files (DeepSeek, Groq, Mistral, Ollama, LocalMlManager → LocalModelManager) consolidated into GenericOpenAiClient
  • Net reduction: −730 lines

Local Model System

40+ downloadable models — all ≤16B params, free, no authentication required.

Model Tiers

Tier RAM Requirement Example Models
Low-end ≤2GB Qwen 2.5 0.5B/1.5B, TinyLlama 1.1B, SmolLM2 1.7B, DeepSeek R1 Distill 1.5B
Mid-range 2–4GB Qwen 2.5 3B/7B, Mistral 7B, Llama 3.2 3B, Phi-3.5 Mini, Granite 8B, Mistral Nemo 12B
High-end 4–8GB+ Qwen 2.5 14B, DeepSeek V2 Lite 16B, StarCoder2 15B

Sources: TheBloke/ and Qwen/ HuggingFace repos only — no login or license acceptance required.

Download Engine (LocalModelManager)

Feature Implementation
Lifecycle Persistent CoroutineScope — downloads survive screen navigation
Progress tracking Average speed tracking + ETA computation
Cancellation HTTP connection disconnect + coroutine cancellation
Resume support Auto-resume interrupted downloads via Range header
Retry logic Exponential backoff (3 attempts: 2s → 4s → 8s)
Retryable errors Timeout, DNS failure, connection reset
Error messages Human-readable — e.g., "Connection timed out. Check your network."
Validation GGUF magic byte validation (GG header)
Result type ValidationResult sealed class (Ok / Missing / SizeMismatch / Corrupted)
Startup behavior Auto-detects and validates installed models

UI — AiPreferencesScreen

Full-featured settings screen with:

Provider Configuration

  • Provider selection dropdown with descriptions
  • API key input with show/hide toggle
  • Model selection per provider (from AiProvider.models)
  • Ollama server configuration

Generation Parameters

  • Temperature
  • Top-K
  • Top-P
  • Repetition / frequency / presence penalty
  • System prompt editor with reset-to-default

Model Management

Section Features
Downloaded Models Shows only installed models; empty state with guidance
Browse Models Collapsible section — all downloadable models with download/delete/select/use buttons
Progress indicator Slim 3dp linear progress bar (matches player style)
Speed/ETA Live download speed (MB/s) and ETA during active downloads
Cancel button One-tap cancellation during download
Confirmation dialogs Download ("Are you sure? X MB") and delete
Error display Card shows descriptive messages instead of generic "Error"

Integration

  • SettingsCategoryScreen updated with AI category

Notifications (AiNotificationManager)

Notification Channels

Channel Importance Purpose
progress LOW Download progress updates
completion DEFAULT Download finished successfully
error HIGH Download failures
info MIN General information

Features

  • Progress notifications update with speed and ETA
  • Completion/error notifications fire automatically via status observer
  • BigTextStyle for full message visibility

Database

Migration: v41 → v42

New entity: ApiCallRecord

Field Description
provider AI provider used
model Model name
endpoint API endpoint called
status_code HTTP response status
response_time Request duration
token_count Input + output tokens
cost_estimate Approximate cost
error_message Error details if failed

Analytics Queries

  • AiUsageDao streamlined with provider-based queries
  • Total API calls per provider
  • Input/output token counts
  • Estimated cost
  • Error rates

Error Handling (AiErrorHandler)

Automatic Classification

  • Rate limit
  • Quota exceeded
  • Billing issues
  • API key issues
  • Model unavailable
  • Network errors

Fallback Strategy

  • Provider fallback chain with recovery model recommendation
  • Structured logging through AiLogger
  • AiProviderException sealed hierarchy for type-safe handling

Supporting Infrastructure

Component Purpose
AiDeviceCapabilities Hardware survey — RAM, CPU, GPU, NNAPI, TFLite, networking
AiPromptTemplateEngine 5 prompt templates for music recommendations + jsonArrayOutput helper
AiSystemPromptEngine Provider-specific system prompts with template variables
AiCacheManager Response caching with configurable TTL and max entries
AiBehaviorDataCollector Listening pattern collection for context-aware recommendations

Refactoring Summary

Key Changes

Before After
5 provider clients 1 GenericOpenAiClient
20 AiSettingsManager setters 1 set() method
4 AiLogger methods 1 log(vararg)
GeminiModelService, deprecated AiMetadataSheet Deleted
AiOrchestrator AiHandler
LocalMlManager LocalModelManager
30 per-provider StateFlows in SettingsViewModel Removed
XML templates Compacted
Duplicate constants Removed

Line Count

Added:   ~2,500 lines
Removed: ~1,900 lines
Net:     +600 lines (after major consolidation)

Breaking Changes

Change Impact
Ollama provider now requires API key + https://ollama.ai/api/v1 No localhost support
LocalMlManager renamed Update imports to LocalModelManager
AiOrchestrator renamed Update imports to AiHandler
ModelFormat enum requires explicit extension parameter Update all usages
LiteRT component removed Conflicts with TFLite — migrate

Files Changed

Added (Key Files)

data/ai/

  • AiHandler
  • AiSettingsManager
  • AiDeviceCapabilities
  • AiErrorHandler
  • AiCacheManager
  • AiLogger
  • AiPromptTemplateEngine
  • AiSystemPromptEngine
  • AiNotificationManager
  • AiBehaviorDataCollector
  • HuggingFaceClient
  • OllamaClient
  • AiUsageAnalytics

data/ai/provider/

  • AiProvider
  • AiProviderEndpoints
  • AiClientFactory
  • GenericOpenAiClient
  • GeminiAiClient
  • AnthropicAiClient
  • AiProviderSupport

data/ai/local/

  • LocalModelConfig
  • LocalModelManager

data/database/

  • ApiCallRecord

presentation/

  • AiPreferencesScreen

Modified

File Changes
SettingsViewModel.kt AI state management, download/notification wiring
SettingsCategoryScreen.kt AI integration
AiPreferencesRepository.kt Analytics support
AiUsageDao.kt Streamlined queries
Database.kt Migration v41→v42

Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│                        AiPreferencesScreen                       │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐ │
│  │  Provider   │  │   Model     │  │   Download Manager      │ │
│  │  Selection  │  │ Management  │  │   (Speed/ETA/Cancel)    │ │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                          AiHandler                               │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────────┐ │
│  │AiSettings   │  │AiError      │  │AiCache                  │ │
│  │Manager      │  │Handler      │  │Manager                  │ │
│  └─────────────┘  └─────────────┘  └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
    ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
    │GenericOpenAi│  │ GeminiAi    │  │AnthropicAi  │
    │Client       │  │Client       │  │Client       │
    └─────────────┘  └─────────────┘  └─────────────┘
              │               │               │
              ▼               ▼               ▼
    ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
    │DeepSeek     │  │   Gemini    │  │   Claude    │
    │Groq         │  │   (REST)    │  │ (Messages)  │
    │Mistral      │  └─────────────┘  └─────────────┘
    │NVIDIA       │
    │Kimi         │
    │GLM          │
    │OpenAI       │
    │OpenRouter   │
    │Ollama       │
    └─────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                      Local Model System                          │
│  ┌─────────────────────────────────────────────────────────────┐│
│  │                   LocalModelManager                          ││
│  │  • Persistent downloads    • Auto-resume (Range header)     ││
│  │  • Speed/ETA tracking      • Exponential backoff retry      ││
│  │  • GGUF validation         • Coroutine lifecycle            ││
│  └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

VoidX3D and others added 30 commits May 28, 2026 17:33
…ptional support and configuration management
- Add Log, CastAudioMimeUtils, IsoBmffAudioCodecDetector imports to CastPlayer
- Fix ArrowBack import in AiPreferencesScreen
- Add AI_PREFERENCES branch to SettingsCategoryScreen when expression
- Remove retryLastMetadataGeneration from PlayerViewModel (feature was removed)
- Fix ColorSchemePair import path in SettingsViewModel

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add new engagement tracking fields for AI behavior analysis
- Enhance engagement data model with play duration, skip counts

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add new AI configuration options for local models
- Enhance provider preferences handling

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add new AI-related dependency injections
- Update provider configurations

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Update AI state management for playlist generation
- Enhance error handling and status tracking

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add listening statistics tracking for AI behavior
- Update player UI state for enhanced features

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Update daily mix section for AI integration
- Enhance song selection logic

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
VoidX3D added 25 commits May 29, 2026 15:00
…oved UX

AiPreferencesScreen:
- Split into distinct sections: provider, online settings, local models,
  context settings, data collection, cache, behavior, usage stats
- Grey out local model section when online provider is selected
- Grey out online API/model settings when local provider is selected
- Add system prompt editor with reset-to-default
- Add context size text input (5-500 range, user-changeable)
- Add data collection & privacy section with 8 granular toggles
- Add cache settings (enable, max entries, TTL)
- Add notification & behavior preferences
- Add usage statistics display with clear button
- Use AiProvider.models dynamically for model dropdowns

SettingsViewModel:
- Add telemetry StateFlows, collectors, and 8 handler functions
- Add get*Once() helpers to AiPreferencesRepository for backup
- Add AI_CONTEXT section to BackupSection enum (sinceVersion 5)
- Create AiContextBackupHandler: exports/restores AI provider prefs,
  context settings, cache config, local ML settings (excludes model files)
- Register new handler in BackupModule DI
- Fix expand_more/expand_less icon references to PascalCase
- Remove duplicate onAiApiKeyChange function overload
- Fix currentAiModel -> currentModel field name in state update
- Fix Int/Float type mismatch for aiTemperature conversion
- Add missing onIncludeUserHabitsChange function
- Remove unused expandVertically/shrinkVertically imports
- Remove dead companion functions from AiProvider enum
- Add import kotlinx.coroutines.flow.first in AiPreferencesRepository
- Add import androidx.compose.ui.res.stringResource in AiPreferencesScreen
- Add AI_CONTEXT branch to ModuleSchemaValidator when expression
…leCard

AiPreferencesRepository:
- Remove 33 per-provider Flow properties (dead code)
- Remove 10 duplicate DEFAULT_*_SYSTEM_PROMPT aliases

SettingsViewModel:
- Remove 33 per-provider StateFlows (dead code)
- Remove 33 per-provider change handlers (use generic functions)
- Consolidate 30+ individual AI collector coroutines into 2 combine() groups
- Remove fragile delay(100) workaround in onAiProviderChange

AiPreferencesScreen:
- Extract reusable CollapsibleCard composable (~80 lines eliminated)
- Add remember() caching in ModelSelectionCard (valueOf + models list)
- Fix contextTextInput desync with remember(maxSongsForContext)

Other:
- Add missing import kotlinx.coroutines.flow.first
- Add missing import androidx.compose.ui.res.stringResource
- Add AI_CONTEXT branch in ModuleSchemaValidator when expression
…ds, slim progress bar, robust api key validation
…A/cancel/retry, fix progress bar import

- Add 10+ new free models: SmolLM2 1.7B, Qwen 2.5 Coder (0.5B/1.5B/7B/14B),
  Llama 3.2 3B, Phi-3.5 Mini, Granite 3.0 2B/8B, Mistral Nemo 12B
- Enrich ModelStatus with bytesDownloaded, totalBytes, speedBytesPerSec, etaSeconds
- Add Pending state for retry/queue scenarios
- Rewrite download engine: average speed tracking, cancel via HTTP disconnect + Job,
  exponential backoff retry (3 attempts), persistent scope surviving navigation
- Improve error classification with user-facing messages
- Add GGUF magic byte validation, ValidationResult sealed class
- Add cancel button to download progress UI with speed/ETA display
- Wire statusMap observer for notifications on Ready/Error
- Auto-detect and validate installed models on startup
- Fix background() unresolved reference in progress bar (add missing import)
…ModelManager, SettingsViewModel

- Replace downloadModel().first() with downloadAndWait() in AiSettingsManager
  (downloadModel no longer returns a Flow)
- Add downloadAndWait() suspend function to LocalModelManager (polling-based)
- Fix ensureActive() receiver mismatch by replacing with yield()
- Add missing LocalModelManager import in SettingsViewModel
- Remove unused ensureActive import from LocalModelManager
…ocus controls

- AiBehaviorDataCollector: derive skip rates, completion stats, recency from playback stats
- UserProfileDigestGenerator: add skip count, genre completion %, recently played section
- AiPlaylistGenerator: inject play count (pc) and last-played hour (lh) into candidate JSON
- AiPromptTemplateEngine: inject user context (skip rate, energy) and 'avoid skipped songs' instruction
- PlaylistCreationDialogs: add Tempo slider (1-5) and Focus on recent toggle
- Add 4 string resources for new lab UI controls
… types

AiPlaylistGenerator: album, year are non-nullable; genre safe-call reordered
AiPromptTemplateEngine: remove year ?: fallback in 3 templates
UserProfileDigestGenerator: album is non-nullable String
- baseline-prof.txt: fix AiPlaylistGenerator constructor (add PlaybackStatsRepository)
- baseline-prof.txt: remove stale AiMetadataGenerator references (deleted class)
- baseline-prof.txt: fix AiStateHolder constructor (remove deleted AiMetadataGenerator param)
- Delete dead AiPromptTemplateEngine.kt (unused, never imported)
- PlaylistCreationDialogs.kt: remove 6 unused imports
…lls, Elvis operators)

- LibraryMediaTabs.kt, LibrarySongsTab.kt: remove redundant smart-casts
- AccountsViewModel.kt: remove unnecessary type casts on combined states
- GenreDetailViewModel.kt: remove Elvis ?: on non-nullable artist/album fields
- PlaybackStateHolder.kt: remove unnecessary safe call on non-null Song
- CastTransferStateHolder.kt: remove unnecessary safe call on non-null HttpURLConnection
- ConnectivityStateHolder.kt: remove unnecessary safe call on non-null String
- RoundedParallaxCarousell.kt: remove redundant .toFloat() on Float width/height
…DisplaySections

The previous edit accidentally removed the grouped.map { (artist, artistSongs) ->
lambda that wraps the albums construction for the ARTIST sort option.
@VoidX3D VoidX3D closed this May 29, 2026
@VoidX3D VoidX3D reopened this May 29, 2026
@VoidX3D VoidX3D closed this May 29, 2026
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