diff --git a/app/androidApp/src/main/kotlin/com/example/aiapp/SessionSettingsScreen.kt b/app/androidApp/src/main/kotlin/com/example/aiapp/SessionSettingsScreen.kt index 239feb8..deaf444 100644 --- a/app/androidApp/src/main/kotlin/com/example/aiapp/SessionSettingsScreen.kt +++ b/app/androidApp/src/main/kotlin/com/example/aiapp/SessionSettingsScreen.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState @@ -300,7 +301,9 @@ fun SessionSettingsScreen( BackHandler(onBack = onDismiss) var tab by remember(sessionId) { mutableIntStateOf(0) } Surface(Modifier.fillMaxSize()) { - Column(Modifier.fillMaxSize()) { + // The keyboard covers the lower half of a form of fields, and this is a screen rather + // than a dialog now -- nothing else is going to move it out of the way. + Column(Modifier.fillMaxSize().imePadding()) { Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp), diff --git a/server/src/session/llama/mod.rs b/server/src/session/llama/mod.rs index 2515eab..c12117b 100644 --- a/server/src/session/llama/mod.rs +++ b/server/src/session/llama/mod.rs @@ -1433,7 +1433,9 @@ fn run_tool( // Read here rather than in the thread: the filter is live, and this is the // call it applies to. let chosen = shared.tools_wanted.lock().unwrap().clone(); - awaiting(shared, &call.id, cancel, move || { + // Keyed apart from the turn's own wait, which the model could otherwise + // collide with by naming a call `generating`. + awaiting(shared, &format!("call:{}", call.id), cancel, move || { match tools.execute(&name, &arguments, cwd.as_deref(), &chosen) { Ok(output) => output, // Reaching the tool failed, which is this server's problem and not @@ -1448,7 +1450,8 @@ fn run_tool( /// The id [`awaiting`] registers a completion under. One name is enough: a /// session runs one turn at a time, and an abandoned turn's entry is taken by -/// the abandoning. +/// the abandoning. A tool call's id is prefixed rather than used raw, so the +/// model cannot name a call this and take the turn's own entry. const GENERATING: &str = "generating"; /// Runs `work` on a thread of its own and waits for it in a way an interrupt