Skip to content

Commit d490fab

Browse files
vNeeL-codeclaude
andcommitted
Support E2B model discovery and improve load error messages
Model search now finds E4B, E2B, and generic gemma.litertlm in both app storage and Downloads. Previously only E4B and generic were checked, so E2B files were silently ignored ("model not found"). Load errors now hint at solutions (try E2B on low-RAM devices, GPU init failure). Model variant logged on discovery. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e5239b8 commit d490fab

1 file changed

Lines changed: 34 additions & 10 deletions

File tree

app/src/main/kotlin/com/gemma/api/GemmaService.kt

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -681,17 +681,33 @@ class GemmaService : Service(), AgentPlatformCallbacks {
681681
val downloadDir = android.os.Environment.getExternalStoragePublicDirectory(
682682
android.os.Environment.DIRECTORY_DOWNLOADS
683683
)
684-
val modelFile = listOf(
685-
// Check app storage first (survives Downloads cleanup)
686-
File(getExternalFilesDir(null), "gemma-3n-E4B-it-int4.litertlm"),
687-
File(getExternalFilesDir(null), "gemma.litertlm"),
688-
// Fallback to Downloads
689-
File(downloadDir, "gemma-3n-E4B-it-int4.litertlm"),
690-
File(downloadDir, "gemma.litertlm")
691-
).firstOrNull { it.exists() }
684+
// Search for any Gemma model variant (E4B preferred, E2B fallback, generic last)
685+
val modelNames = listOf(
686+
"gemma-3n-E4B-it-int4.litertlm",
687+
"gemma-3n-E2B-it-int4.litertlm",
688+
"gemma.litertlm"
689+
)
690+
val searchDirs = listOf(
691+
getExternalFilesDir(null), // App storage (survives Downloads cleanup)
692+
downloadDir // Downloads folder
693+
)
694+
val modelFile = searchDirs.flatMap { dir ->
695+
modelNames.map { name -> File(dir, name) }
696+
}.firstOrNull { it.exists() }
697+
698+
if (modelFile != null) {
699+
val variant = when {
700+
modelFile.name.contains("E4B") -> "E4B (full)"
701+
modelFile.name.contains("E2B") -> "E2B (lite)"
702+
else -> "unknown variant"
703+
}
704+
Timber.i("📦 Found model: ${modelFile.name} ($variant) in ${modelFile.parent}")
705+
}
692706

693707
if (modelFile == null) {
694-
updateNotification("ERROR: No model found")
708+
val searchedPaths = searchDirs.mapNotNull { it?.absolutePath }
709+
Timber.e("No model found! Searched: $searchedPaths for: $modelNames")
710+
updateNotification("ERROR: No model found. Place .litertlm in app folder or Downloads")
695711
return
696712
}
697713

@@ -700,7 +716,15 @@ class GemmaService : Service(), AgentPlatformCallbacks {
700716
// Inject Identity Prompt (Static)
701717
val error = newEngine.initialize(modelFile.absolutePath, com.gemma.api.logic.ContextManager.BASE_SYSTEM_PROMPT)
702718
if (error != null) {
703-
updateNotification("Load Error: $error")
719+
val hint = when {
720+
error.contains("memory", ignoreCase = true) || error.contains("OOM", ignoreCase = true) ->
721+
" (Try E2B model on this device)"
722+
error.contains("GPU", ignoreCase = true) ->
723+
" (GPU init failed — device may not support this model)"
724+
else -> ""
725+
}
726+
Timber.e("Model load failed: $error")
727+
updateNotification("Load Error: ${error.take(80)}$hint")
704728
return
705729
}
706730

0 commit comments

Comments
 (0)