fix(jetbrains): handle queued prompt deletion misses

This commit is contained in:
kirillk
2026-07-27 12:14:33 -04:00
parent ec1e67b8dc
commit 0178e3361b
4 changed files with 24 additions and 19 deletions
@@ -467,11 +467,19 @@ class SessionController(
fun deleteQueuedMessage(message: String) {
assertEdt()
val id = sid ?: return
capture("Conversation Queued Message Removed", sessionProps(id))
cs.launch {
try {
sessions.deleteMessage(id, directory, message)
val ok = sessions.deleteMessage(id, directory, message)
if (!ok) {
capture("Session Error", sessionProps(id) + mapOf("context" to "delete-message", "errorClass" to "DeleteMiss"))
LOG.warn("${ChatLogSummary.sid(id)} kind=deleteMessage missed message=$message")
return@launch
}
capture("Conversation Queued Message Removed", sessionProps(id))
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
capture("Session Error", sessionProps(id) + mapOf("context" to "delete-message", "errorClass" to e::class.java.name))
LOG.warn("${ChatLogSummary.sid(id)} kind=deleteMessage failed message=${e.message}", e)
}
}
@@ -33,7 +33,6 @@ internal class MessageToolbar(
buttons.forEach { next(it) }
next(button)
}
private var custom: JComponent? = null
init {
isOpaque = false
@@ -42,12 +41,10 @@ internal class MessageToolbar(
@RequiresEdt
fun sync(value: Boolean) {
val controls = customButtons()
if (isVisible == value && button.isEnabled == value && controls.all { it.isEnabled == value }) return
if (isVisible == value && button.isEnabled == value) return
isVisible = value
button.isEnabled = value
buttons.forEach { it.isEnabled = value }
controls.forEach { it.isEnabled = value }
revalidate()
repaint()
}
@@ -63,16 +60,6 @@ internal class MessageToolbar(
@RequiresEdt
fun copyButton() = button
@RequiresEdt
fun setCustom(node: JComponent?) {
if (custom === node) return
remove(custom ?: row)
custom = node
add(node ?: row)
revalidate()
repaint()
}
fun placeholder(): JComponent = object : JPanel() {
init {
isOpaque = false
@@ -91,6 +78,4 @@ internal class MessageToolbar(
copy.dismiss()
super.removeNotify()
}
private fun customButtons() = custom?.components?.filterIsInstance<javax.swing.AbstractButton>().orEmpty()
}
@@ -67,7 +67,6 @@ class TurnView(
val view = MessageView(msg, openFile, style, openUrl, selection, openAttachment, resize, repo, hover, revert)
messages[msg.info.id] = view
add(view)
if (msg.info.id == id && deleteQueued != null) view.setQueued(false) { deleteQueued.invoke(id) }
syncCopyToolbars()
revalidate()
return view
@@ -127,6 +127,19 @@ class PromptLifecycleTest : SessionControllerTestBase() {
flush()
assertEquals(listOf(ai.kilocode.client.testing.FakeSessionRpcApi.MessageDeleteCall("ses_test", "/test", "u2")), rpc.messageDeletes)
assertTrue(appRpc.telemetry.any { it.event == "Conversation Queued Message Removed" })
}
fun `test delete queued message miss captures error`() {
val (c, _, _) = prompted()
rpc.messageDeleteResult = false
edt { c.deleteQueuedMessage("u2") }
flush()
assertEquals(listOf(ai.kilocode.client.testing.FakeSessionRpcApi.MessageDeleteCall("ses_test", "/test", "u2")), rpc.messageDeletes)
assertFalse(appRpc.telemetry.any { it.event == "Conversation Queued Message Removed" })
assertTrue(appRpc.telemetry.any { it.event == "Session Error" && it.properties["context"] == "delete-message" })
}
fun `test PermissionAsked moves state to AwaitingPermission`() {