From 709efd09a221f710bc32f9abb76b1d389ed4d629 Mon Sep 17 00:00:00 2001 From: kirillk Date: Tue, 2 Jun 2026 14:38:14 -0400 Subject: [PATCH] fix(kilo-jetbrains): log settings saves --- .../backend/app/KiloBackendAppService.kt | 11 +++++++++- .../ai/kilocode/client/app/KiloAppService.kt | 9 +++++++- .../settings/models/ModelsSettingsUi.kt | 21 ++++++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/packages/kilo-jetbrains/backend/src/main/kotlin/ai/kilocode/backend/app/KiloBackendAppService.kt b/packages/kilo-jetbrains/backend/src/main/kotlin/ai/kilocode/backend/app/KiloBackendAppService.kt index 9846109f157..2a4d6ad350d 100644 --- a/packages/kilo-jetbrains/backend/src/main/kotlin/ai/kilocode/backend/app/KiloBackendAppService.kt +++ b/packages/kilo-jetbrains/backend/src/main/kotlin/ai/kilocode/backend/app/KiloBackendAppService.kt @@ -217,6 +217,8 @@ class KiloBackendAppService private constructor( val http = connection.apiClient ?: throw IllegalStateException("Not connected") val current = _appState.value as? KiloAppState.Ready ?: throw IllegalStateException("Kilo backend is not ready") val body = KiloCliDataParser.buildConfigPatch(patch) + val summary = summary(patch) + log.info("Global config patch: started $summary") val request = Request.Builder() .url("http://127.0.0.1:$port/global/config") .header("Accept", "application/json") @@ -226,12 +228,14 @@ class KiloBackendAppService private constructor( http.newCall(request).execute().use { response -> if (!response.isSuccessful) { val text = response.body?.string() - log.warn("Global config patch failed: HTTP ${response.code} ${response.message} ${text.orEmpty()}") + log.warn("Global config patch failed: HTTP ${response.code} ${response.message} $summary ${text.orEmpty()}") throw IllegalStateException("Global config patch failed: HTTP ${response.code} ${response.message}") } } } + log.info("Global config patch: saved $summary") refreshConfigState() + log.info("Global config patch: state refreshed $summary") return (_appState.value as? KiloAppState.Ready) ?: current } @@ -809,6 +813,11 @@ class KiloBackendAppService private constructor( } } +private fun summary(patch: ConfigPatchDto): String { + val values = patch.values.keys.sorted().joinToString(",").ifEmpty { "none" } + return "values=$values agents=${patch.agents.size}" +} + /** * Result of a data fetch — either a value or an error with details. */ diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/app/KiloAppService.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/app/KiloAppService.kt index 38f7a1d8dff..d18532b7394 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/app/KiloAppService.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/app/KiloAppService.kt @@ -216,11 +216,13 @@ class KiloAppService internal constructor( } suspend fun updateConfig(patch: ConfigPatchDto): KiloAppStateDto? = try { + LOG.info("config update: sending RPC ${summary(patch)}") val next = call { updateConfig(patch) } _state.value = next + LOG.info("config update: RPC completed ${summary(patch)}") next } catch (e: Exception) { - LOG.warn("config update failed", e) + LOG.warn("config update failed ${summary(patch)}", e) null } @@ -310,3 +312,8 @@ class KiloAppService internal constructor( _state.value = current.copy(profile = profile, progress = progress) } } + +private fun summary(patch: ConfigPatchDto): String { + val values = patch.values.keys.sorted().joinToString(",").ifEmpty { "none" } + return "values=$values agents=${patch.agents.size}" +} diff --git a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/settings/models/ModelsSettingsUi.kt b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/settings/models/ModelsSettingsUi.kt index 6bc942b5a05..958053e5619 100644 --- a/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/settings/models/ModelsSettingsUi.kt +++ b/packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/settings/models/ModelsSettingsUi.kt @@ -17,7 +17,9 @@ import ai.kilocode.client.settings.ui.SettingsRows import ai.kilocode.client.ui.layout.HAlign import ai.kilocode.client.ui.layout.VAlign import ai.kilocode.client.ui.layout.align +import ai.kilocode.log.KiloLog import ai.kilocode.rpc.dto.AgentDto +import ai.kilocode.rpc.dto.ConfigPatchDto import ai.kilocode.rpc.dto.KiloAppStateDto import ai.kilocode.rpc.dto.KiloAppStatusDto import ai.kilocode.rpc.dto.LoadErrorDto @@ -48,6 +50,10 @@ internal class ModelsSettingsUi( private val directory: String? = null, ) : SettingsPanel() { + companion object { + private val LOG = KiloLog.create(ModelsSettingsUi::class.java) + } + private val form = ModelsSettingsContent(app, ::update, ::selectSubagent) private val defaults = form.defaults private val small = form.small @@ -100,6 +106,7 @@ internal class ModelsSettingsUi( val next = draft val patch = patch(prev, next) if (patch.values.isEmpty() && patch.agents.isEmpty()) return + LOG.info("model settings save: started ${summary(patch)}") pending = next saving = true saveError = null @@ -108,10 +115,16 @@ internal class ModelsSettingsUi( app.updateConfigAsync(patch) { state -> ApplicationManager.getApplication().invokeLater({ if (disposed) { - if (state == null) KiloNotifications.error(KiloBundle.message("settings.models.save.failed")) + if (state == null) { + LOG.warn("model settings save: failed after dispose ${summary(patch)}") + KiloNotifications.error(KiloBundle.message("settings.models.save.failed")) + } else { + LOG.info("model settings save: completed after dispose ${summary(patch)}") + } return@invokeLater } if (state != null) { + LOG.info("model settings save: completed ${summary(patch)}") appState = state val base = modelsDraft(state.config, agents) baseline = if (savedMatches(base, next)) base else next @@ -127,6 +140,7 @@ internal class ModelsSettingsUi( draft = next pending = null saving = false + LOG.warn("model settings save: failed ${summary(patch)}") saveError = KiloBundle.message("settings.models.save.failed") sync() }, ModalityState.any()) @@ -391,6 +405,11 @@ internal class ModelsSettingsUi( private const val KILO_PROVIDER = "kilo" +private fun summary(patch: ConfigPatchDto): String { + val values = patch.values.keys.sorted().joinToString(",").ifEmpty { "none" } + return "values=$values agents=${patch.agents.size}" +} + private class ModelsSettingsContent( app: KiloAppService, update: (ModelsDraft.() -> ModelsDraft) -> Unit,