mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-10-30 19:32:39 +08:00
fix(kilo-jetbrains): show sign-in banner in models settings
This commit is contained in:
+3
-1
@@ -70,8 +70,10 @@ internal fun modelsStatus(
|
||||
if (saving) return ModelsStatus.SAVING
|
||||
if (!ready) return ModelsStatus.UNAVAILABLE
|
||||
if (loading) return ModelsStatus.LOADING
|
||||
if (providers == null) return if (errors.isNotEmpty()) ModelsStatus.LOAD_FAILED else ModelsStatus.LOADING
|
||||
if (providers == null) return ModelsStatus.LOAD_FAILED
|
||||
if (items == 0) return ModelsStatus.NO_PROVIDERS
|
||||
if (errors.any { it.resource == "agents" }) return ModelsStatus.MODES_FAILED
|
||||
return ModelsStatus.READY
|
||||
}
|
||||
|
||||
internal fun modelsLoginBannerVisible(ready: Boolean, authenticated: Boolean): Boolean = ready && !authenticated
|
||||
|
||||
+45
-2
@@ -6,6 +6,7 @@ import ai.kilocode.client.plugin.KiloBundle
|
||||
import ai.kilocode.client.session.ui.ReasoningPicker
|
||||
import ai.kilocode.client.session.ui.model.ModelPicker
|
||||
import ai.kilocode.client.session.ui.model.ModelText
|
||||
import ai.kilocode.client.settings.profile.UserProfileConfigurable
|
||||
import ai.kilocode.client.settings.profile.edt
|
||||
import ai.kilocode.client.settings.ui.SettingsRow
|
||||
import ai.kilocode.client.settings.ui.SettingsRows
|
||||
@@ -20,8 +21,16 @@ import ai.kilocode.rpc.dto.KiloAppStatusDto
|
||||
import ai.kilocode.rpc.dto.LoadErrorDto
|
||||
import ai.kilocode.rpc.dto.ModelsWorkspaceDto
|
||||
import ai.kilocode.rpc.dto.ProvidersDto
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.options.Configurable
|
||||
import com.intellij.openapi.options.ConfigurableWithId
|
||||
import com.intellij.openapi.options.ShowSettingsUtil
|
||||
import com.intellij.openapi.options.ex.Settings
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.ui.EditorNotificationPanel
|
||||
import com.intellij.ui.InlineBanner
|
||||
import com.intellij.ui.TitledSeparator
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import com.intellij.ui.components.JBScrollPane
|
||||
@@ -33,6 +42,8 @@ import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.awt.BorderLayout
|
||||
import java.util.function.Predicate
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JPanel
|
||||
|
||||
internal class ModelsSettingsUi(
|
||||
@@ -43,6 +54,10 @@ internal class ModelsSettingsUi(
|
||||
) : JPanel(BorderLayout()) {
|
||||
|
||||
private val status = JBLabel(KiloBundle.message("settings.models.loading"))
|
||||
private val banner = InlineBanner(
|
||||
KiloBundle.message("settings.models.login.message"),
|
||||
EditorNotificationPanel.Status.Warning,
|
||||
).showCloseButton(false)
|
||||
private val content = Stack.vertical()
|
||||
private val rows = SettingsRows()
|
||||
private val modes = SettingsRows()
|
||||
@@ -76,6 +91,9 @@ internal class ModelsSettingsUi(
|
||||
picker.picker.onFavoriteToggle = { app.toggleModelFavorite(it.provider, it.id) }
|
||||
}
|
||||
|
||||
banner.addAction(KiloBundle.message("settings.models.login.action"), Runnable { openProfile(banner) })
|
||||
content.next(banner)
|
||||
content.gap(UiStyle.Gap.md())
|
||||
content.next(status)
|
||||
content.gap(UiStyle.Gap.lg())
|
||||
content.next(TitledSeparator(KiloBundle.message("settings.models.displayName")))
|
||||
@@ -240,15 +258,20 @@ internal class ModelsSettingsUi(
|
||||
checkEdt()
|
||||
allItems = items(false)
|
||||
val smallItems = items(true)
|
||||
val hasDir = dir != null || directory != null
|
||||
val state = modelsStatus(
|
||||
ready = appState.status == KiloAppStatusDto.READY,
|
||||
loading = loading || (appState.status == KiloAppStatusDto.READY && !loaded && dir != null),
|
||||
ready = appState.status == KiloAppStatusDto.READY && hasDir,
|
||||
loading = loading || (appState.status == KiloAppStatusDto.READY && !loaded && hasDir),
|
||||
providers = providers,
|
||||
items = allItems.size,
|
||||
errors = errors,
|
||||
saving = saving,
|
||||
)
|
||||
val ready = state == ModelsStatus.READY || state == ModelsStatus.MODES_FAILED
|
||||
banner.isVisible = modelsLoginBannerVisible(
|
||||
ready = appState.status == KiloAppStatusDto.READY,
|
||||
authenticated = appState.profile != null,
|
||||
)
|
||||
if (!saving) {
|
||||
when (state) {
|
||||
ModelsStatus.UNAVAILABLE -> {
|
||||
@@ -348,6 +371,26 @@ internal class ModelsSettingsUi(
|
||||
update { copy(subagent = item.key, variant = variant) }
|
||||
}
|
||||
|
||||
private fun openProfile(src: JComponent) {
|
||||
val settings = Settings.KEY.getData(DataManager.getInstance().getDataContext(src))
|
||||
if (settings != null) {
|
||||
val cfg = settings.find(UserProfileConfigurable.ID)
|
||||
if (cfg != null) {
|
||||
settings.select(cfg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val project = ProjectManager.getInstance().openProjects.firstOrNull { !it.isDefault }
|
||||
ShowSettingsUtil.getInstance().showSettingsDialog(
|
||||
project,
|
||||
Predicate { cfg: Configurable ->
|
||||
cfg is ConfigurableWithId && cfg.getId() == UserProfileConfigurable.ID
|
||||
},
|
||||
{ cfg: Configurable -> cfg.focusOn(UserProfileConfigurable.FOCUS_ACCOUNT_COMBO) },
|
||||
)
|
||||
}
|
||||
|
||||
@RequiresEdt
|
||||
private fun update(fn: ModelsDraft.() -> ModelsDraft) {
|
||||
checkEdt()
|
||||
|
||||
@@ -207,6 +207,8 @@ settings.models.unavailable=Models are unavailable until Kilo finishes loading.
|
||||
settings.models.load.failed=Failed to load model settings
|
||||
settings.models.noProviders=No providers available
|
||||
settings.models.modes.failed=Failed to load per-mode settings
|
||||
settings.models.login.message=Sign in to Kilo Code to access account-backed models and manage billing.
|
||||
settings.models.login.action=Open User Profile
|
||||
settings.models.save.failed=Failed to save model settings
|
||||
settings.models.save.pending=Saving model settings...
|
||||
settings.models.reset=Reset
|
||||
|
||||
+23
@@ -7,7 +7,9 @@ import ai.kilocode.rpc.dto.LoadErrorDto
|
||||
import ai.kilocode.rpc.dto.ProvidersDto
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ModelsSettingsStateTest {
|
||||
|
||||
@@ -96,6 +98,20 @@ class ModelsSettingsStateTest {
|
||||
assertEquals(ModelsStatus.LOAD_FAILED, status)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `models status reports missing providers after loading completes`() {
|
||||
val status = modelsStatus(
|
||||
ready = true,
|
||||
loading = false,
|
||||
providers = null,
|
||||
items = 0,
|
||||
errors = emptyList(),
|
||||
saving = false,
|
||||
)
|
||||
|
||||
assertEquals(ModelsStatus.LOAD_FAILED, status)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `models status reports app unavailable`() {
|
||||
val status = modelsStatus(
|
||||
@@ -109,4 +125,11 @@ class ModelsSettingsStateTest {
|
||||
|
||||
assertEquals(ModelsStatus.UNAVAILABLE, status)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `login banner shows only when ready and unauthenticated`() {
|
||||
assertTrue(modelsLoginBannerVisible(ready = true, authenticated = false))
|
||||
assertFalse(modelsLoginBannerVisible(ready = true, authenticated = true))
|
||||
assertFalse(modelsLoginBannerVisible(ready = false, authenticated = false))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user