diff --git a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderListScreen.kt b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderListScreen.kt index 31364d0b..fe6b1d60 100644 --- a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderListScreen.kt +++ b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderListScreen.kt @@ -98,7 +98,12 @@ fun LlmProviderListScreen( } providers.forEachIndexed { index, provider -> - LlmProviderRow(provider = provider, onClick = { onEditProvider(provider.id) }) + LlmProviderRow( + provider = provider, + onClick = if (provider.kind != LlmProviderKind.ON_DEVICE) { + { onEditProvider(provider.id) } + } else null, + ) if (index != providers.lastIndex) { HorizontalDivider(modifier = Modifier.padding(vertical = 4.dp)) } @@ -108,7 +113,7 @@ fun LlmProviderListScreen( /** A single provider row — resolves [LlmProvider.checkAvailability] asynchronously per-row. */ @Composable -private fun LlmProviderRow(provider: LlmProvider, onClick: () -> Unit) { +private fun LlmProviderRow(provider: LlmProvider, onClick: (() -> Unit)?) { // produceState re-runs the suspend block whenever `provider` changes identity; starts at // `null` ("Checking availability…") so we never render an optimistic default. val availability by produceState(initialValue = null, provider) { @@ -118,7 +123,7 @@ private fun LlmProviderRow(provider: LlmProvider, onClick: () -> Unit) { Row( modifier = Modifier .fillMaxWidth() - .clickable(onClick = onClick) + .then(if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier) .padding(vertical = 10.dp), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, @@ -143,12 +148,14 @@ private fun LlmProviderRow(provider: LlmProvider, onClick: () -> Unit) { Row(verticalAlignment = Alignment.CenterVertically) { ProviderStatusIndicator(availability) - Spacer(modifier = Modifier.width(4.dp)) - Icon( - Icons.Default.ChevronRight, - contentDescription = "Edit", - tint = MaterialTheme.colorScheme.onSurfaceVariant, - ) + if (onClick != null) { + Spacer(modifier = Modifier.width(4.dp)) + Icon( + Icons.Default.ChevronRight, + contentDescription = "Edit", + tint = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } } } } diff --git a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderSettings.kt b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderSettings.kt index f55c69c0..9743d21b 100644 --- a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderSettings.kt +++ b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/settings/LlmProviderSettings.kt @@ -30,6 +30,7 @@ import dev.stapler.stelekit.llm.CustomOpenAiCompatibleLlmProvider import dev.stapler.stelekit.llm.CustomProviderConfig import dev.stapler.stelekit.llm.LlmCredentialStore import dev.stapler.stelekit.llm.LlmFeature +import dev.stapler.stelekit.llm.LlmProviderKind import dev.stapler.stelekit.llm.LlmProviderRegistry import dev.stapler.stelekit.llm.LlmSettings import io.ktor.client.HttpClient @@ -79,9 +80,10 @@ fun LlmProviderSettings( onEditProvider = { id -> if (id.startsWith("custom:")) { editingCustomProviderId = id - } else { + } else if (registry.find(id)?.kind == LlmProviderKind.REMOTE) { editingBuiltInProviderId = id } + // ON_DEVICE and unknown kinds have no credentials — click is intentionally a no-op }, ) diff --git a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/SuggestionBottomSheet.kt b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/SuggestionBottomSheet.kt index 38cf1526..25e1725e 100644 --- a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/SuggestionBottomSheet.kt +++ b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/SuggestionBottomSheet.kt @@ -90,7 +90,7 @@ fun SuggestionBottomSheet( if (state.llmError != null) { Text( - text = "Could not reach LLM", + text = state.llmError, style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.error, modifier = Modifier.padding(top = 8.dp), diff --git a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/TagChipRow.kt b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/TagChipRow.kt index 773d3e06..8db31c29 100644 --- a/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/TagChipRow.kt +++ b/kmp/src/commonMain/kotlin/dev/stapler/stelekit/ui/components/tags/TagChipRow.kt @@ -61,7 +61,7 @@ fun TagChipRow( if (llmError != null) { Spacer(modifier = Modifier.width(8.dp)) Text( - text = "Could not reach LLM", + text = llmError, style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), )