Skip to content

Commit dbe8152

Browse files
Adjust model menu ordering, warnings, and payment/system text
1 parent 3ac988f commit dbe8152

3 files changed

Lines changed: 63 additions & 19 deletions

File tree

app/src/main/kotlin/com/google/ai/sample/MainActivityDialogs.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import androidx.compose.material3.TextButton
1515
import androidx.compose.runtime.Composable
1616
import androidx.compose.ui.Alignment
1717
import androidx.compose.ui.Modifier
18+
import androidx.compose.ui.graphics.Color
1819
import androidx.compose.ui.unit.dp
1920
import androidx.compose.ui.window.Dialog
2021

@@ -62,9 +63,13 @@ internal fun PaymentMethodDialog(
6263
Column {
6364
Button(
6465
onClick = onPayPalClick,
65-
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)
66+
// Do not actually disable this button; keep click behavior enabled.
67+
modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp),
68+
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
69+
containerColor = Color.Gray
70+
)
6671
) {
67-
Text("PayPal (2,60 €/Month)")
72+
Text("PayPal (2,90 €/Month)")
6873
}
6974
Button(
7075
onClick = onGooglePlayClick,

app/src/main/kotlin/com/google/ai/sample/MenuScreen.kt

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ data class MenuItem(
9898
val descriptionResId: Int
9999
)
100100

101+
private val STRIKETHROUGH_MODELS = listOf(
102+
ModelOption.GEMMA_3_27B_IT,
103+
ModelOption.MISTRAL_LARGE_3,
104+
ModelOption.GEMINI_FLASH_LIVE_PREVIEW,
105+
ModelOption.GEMINI_FLASH_LITE_PREVIEW,
106+
ModelOption.QWEN3_5_4B_OFFLINE
107+
)
108+
101109
@Composable
102110
fun MenuScreen(
103111
innerPadding: PaddingValues,
@@ -201,12 +209,33 @@ fun MenuScreen(
201209
expanded = expanded,
202210
onDismissRequest = { expanded = false }
203211
) {
204-
val orderedModels = ModelOption.values().toList()
212+
val allModels = ModelOption.values().toList()
213+
val vercelModels = allModels.filter {
214+
it.apiProvider == ApiProvider.VERCEL && !STRIKETHROUGH_MODELS.contains(it)
215+
}
216+
val normalModels = allModels.filter {
217+
it != ModelOption.MISTRAL_MEDIUM_3_1 &&
218+
it.apiProvider != ApiProvider.VERCEL &&
219+
!STRIKETHROUGH_MODELS.contains(it)
220+
}
221+
val orderedModels = listOf(ModelOption.MISTRAL_MEDIUM_3_1) +
222+
normalModels +
223+
vercelModels +
224+
STRIKETHROUGH_MODELS
205225

206226
orderedModels.forEach { modelOption ->
207227
DropdownMenuItem(
208228
text = {
209-
Text(modelOption.displayName + (modelOption.size?.let { " - $it" } ?: ""))
229+
// Do not actually disable these models. They must remain selectable for testing/debug purposes.
230+
val itemTextStyle = if (STRIKETHROUGH_MODELS.contains(modelOption)) {
231+
MaterialTheme.typography.bodyLarge.copy(textDecoration = TextDecoration.LineThrough)
232+
} else {
233+
MaterialTheme.typography.bodyLarge
234+
}
235+
Text(
236+
text = modelOption.displayName + (modelOption.size?.let { " - $it" } ?: ""),
237+
style = itemTextStyle
238+
)
210239
},
211240
onClick = {
212241
expanded = false
@@ -252,6 +281,26 @@ fun MenuScreen(
252281
}
253282
}
254283
}
284+
285+
val modelHint = when (selectedModel) {
286+
ModelOption.GEMMA_3_27B_IT -> "Google doesn't support screenshots in the API for this model."
287+
ModelOption.GPT_OSS_120B -> "This is a pure text model\nCerebras sometimes discontinues free access in the Free Tier, displaying an \"Error 404: gpt-oss-120b does not exist or you do not have access to it\" message, or changes the rate limits."
288+
ModelOption.MISTRAL_LARGE_3 -> "Mistral AI rejects requests containing non-black images with a 429 Error: Rate limit exceeded response"
289+
ModelOption.GEMINI_3_FLASH -> "Google often rejects requests to this model with a 503 Model is exhausted error"
290+
ModelOption.PUTER_GLM5 -> "This model is expensive and uses up the free quota quickly. Consider GPT 5.4 nano"
291+
ModelOption.GPT_5_1_CODEX_MAX,
292+
ModelOption.GPT_5_1_CODEX_MINI,
293+
ModelOption.GPT_5_NANO -> "Vercel requires a credit card"
294+
else -> ""
295+
}
296+
if (modelHint.isNotBlank()) {
297+
Spacer(modifier = Modifier.height(8.dp))
298+
Text(
299+
text = modelHint,
300+
style = MaterialTheme.typography.bodyMedium,
301+
color = MaterialTheme.colorScheme.onSurfaceVariant
302+
)
303+
}
255304
}
256305
}
257306
}
@@ -583,29 +632,19 @@ fun MenuScreen(
583632
withStyle(boldStyle) { append("API Keys") }
584633
append(" are automatically switched if multiple are inserted and one is exhausted.\n")
585634

586-
append("")
587-
withStyle(boldStyle) { append("GPT-oss 120b") }
588-
append(" is a pure text model.\n")
589-
append("")
590-
591-
withStyle(boldStyle) { append("Gemma 27B IT") }
592-
append(" cannot handle screenshots in the API.\n")
635+
append("• Models with a line through them do not work properly.\n")
593636
append("• GPT models (")
594637
withStyle(boldStyle) { append("Vercel") }
595638
append(") have a free budget of \$5 per month and a credit card is necessary.\n")
596639
append("GPT-5.1 Input: \$1.25/M Output: \$10.00/M\n")
597640
append("GPT-5.1 mini Input: \$0.25/M Output: \$2.00/M\n")
598641
append("GPT-5 nano Input: \$0.05/M Output: \$0.40/M\n")
599642
append("• When a language model repeats a token, Top K and Top P must be lowered.\n")
600-
append("• There are ")
601-
withStyle(boldStyle) { append("rate limits") }
602-
append(" for free use of ")
603-
withStyle(boldStyle) { append("Gemini models") }
604-
append(". The less powerful the models are, the more you can use them. The limits range from a maximum of 5 to 30 calls per minute. After each screenshot (every 2-3 seconds) the LLM must respond again. More information is available at ")
643+
append("• Google has recently significantly tightened its rate limits and is fluctuating widely with its free quota. Try it for yourself. More information is available at ")
605644

606-
pushStringAnnotation(tag = "URL", annotation = "https://ai.google.dev/gemini-api/docs/rate-limits")
645+
pushStringAnnotation(tag = "URL", annotation = "https://aistudio.google.com/rate-limit")
607646
withStyle(style = SpanStyle(color = MaterialTheme.colorScheme.primary, textDecoration = TextDecoration.Underline)) {
608-
append("https://ai.google.dev/gemini-api/docs/rate-limits")
647+
append("https://aistudio.google.com/rate-limit")
609648
}
610649
pop()
611650
}

app/src/main/kotlin/com/google/ai/sample/util/SystemMessagePreferences.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ object SystemMessagePreferences {
1414
private const val KEY_FIRST_START_COMPLETED = "first_start_completed" // New flag
1515

1616
// Content from pasted_content.txt
17-
private const val DEFAULT_SYSTEM_MESSAGE_ON_FIRST_START = """You are on an App on a Smartphone. Your app is called Screen Operator. You start from this app. Proceed step by step! DON'T USE TOOL CODE! You must operate the screen with exactly following commands: "home()" "back()" "recentApps()" "openApp("sample")" for buttons and words: "click("sample")" "longClick("sample")" "tapAtCoordinates(x, y)" "tapAtCoordinates(x percent of screen%, y percent of screen%)" "scrollDown()" "scrollUp()" "scrollLeft()" "scrollRight()" "scrollDown(x, y, how much pixel to scroll, duration in milliseconds)" "scrollUp(x, y, how much pixel to scroll, duration in milliseconds)" "scrollLeft(x, y, how much pixel to scroll, duration in milliseconds)" "scrollRight(x, y, how much pixel to scroll, duration in milliseconds)" "scrollDown(x percent of screen%, y percent of screen%, how much percent to scroll%, duration in milliseconds)" "scrollUp(x percent of screen%, y percent of screen%, how much percent to scroll, duration in milliseconds)" "scrollLeft(x percent of screen%, y percent of screen%, how much percent to scroll, duration in milliseconds)" "scrollRight(x percent of screen%, y percent of screen%, how much percent to scroll, duration in milliseconds)" scroll status bar down: "scrollUp(540, 0, 1100, 50)" "takeScreenshot()" To write text, search and click the textfield thereafter: "writeText("sample text")" You need to write the already existing text, if it should continue exist. If the keyboard is displayed, you can press "Enter()". Otherwise, you have to open the keyboard by clicking on the text field. You can see the screen and get additional Informations about them with: "takeScreenshot()" You need this command at the end of every message until you are finish. When you're done don't say "takeScreenshot()" Your task is:"""
17+
private const val DEFAULT_SYSTEM_MESSAGE_ON_FIRST_START = """You are on an App on a Smartphone. Your app is called Screen Operator. You start from this app. Proceed step by step! DON'T USE TOOL CODE! You must operate the screen with exactly following commands: "home()" "back()" "recentApps()" "openApp("sample")" for buttons and words: "click("sample")" "longClick("sample")" "tapAtCoordinates(x, y)" "tapAtCoordinates(x percent of screen%, y percent of screen%)" "scrollDown()" "scrollUp()" "scrollLeft()" "scrollRight()" "scrollDown(x, y, how much pixel to scroll, duration in milliseconds)" "scrollUp(x, y, how much pixel to scroll, duration in milliseconds)" "scrollLeft(x, y, how much pixel to scroll, duration in milliseconds)" "scrollRight(x, y, how much pixel to scroll, duration in milliseconds)" "scrollDown(x percent of screen%, y percent of screen%, how much percent to scroll%, duration in milliseconds)" "scrollUp(x percent of screen%, y percent of screen%, how much percent to scroll, duration in milliseconds)" "scrollLeft(x percent of screen%, y percent of screen%, how much percent to scroll, duration in milliseconds)" "scrollRight(x percent of screen%, y percent of screen%, how much percent to scroll, duration in milliseconds)" scroll status bar down: "scrollUp(540, 0, 1100, 50)" "takeScreenshot()" To write text, search and click the textfield thereafter: "writeText("sample text")" You need to write the already existing text, if it should continue exist. If the keyboard is displayed, you can press "Enter()". Otherwise, you have to open the keyboard by clicking on the text field. Don't write the commands if you're just planing about it or messaging me. You can see the screen and get additional Informations about them with: "takeScreenshot()" You need this command at the end of every message until you are finish. When you're done don't say "takeScreenshot()" Your task is:"""
1818
private fun prefs(context: Context) = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
1919

2020
/**

0 commit comments

Comments
 (0)