From 1bd56270b32be28771fae6360e1102908f125e26 Mon Sep 17 00:00:00 2001 From: M57 <41645758+Hy4ri@users.noreply.github.com> Date: Wed, 24 Jun 2026 23:54:47 +0300 Subject: [PATCH] fix(#206): read clarify.request question/choices from gateway (#355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#206): read clarify.request question/choices from gateway The Hermes TUI gateway sends clarify.request payloads with "question" and "choices" fields, but the Android parser was looking for "text" and "options" — so the text was always null and the dialog showed only the input box. Fix reads "question"/"choices" first, falls back to "text"/"options" for backward compat. Test added for the new field names; existing test for legacy names still passes. * fix(#206): clear default text in clarify input field The input box was pre-filled with the clarify question text because the initial state was set to clarify.text instead of empty string. * fix: use JsonRpcResponse instead of undefined WsResponse in EventParserTest --------- Co-authored-by: M57 --- .../m57/hermescontrol/data/ws/EventParser.kt | 10 +++++-- .../m57/hermescontrol/ui/chat/ChatScreen.kt | 2 +- .../hermescontrol/data/ws/EventParserTest.kt | 26 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/m57/hermescontrol/data/ws/EventParser.kt b/app/src/main/java/com/m57/hermescontrol/data/ws/EventParser.kt index 2f033af7..a9f21913 100644 --- a/app/src/main/java/com/m57/hermescontrol/data/ws/EventParser.kt +++ b/app/src/main/java/com/m57/hermescontrol/data/ws/EventParser.kt @@ -81,8 +81,14 @@ object EventParser { } "clarify.request" -> { - val text = payload?.get("text") as? String - val rawOptions = payload?.get("options") + // Gateway sends "question"/"choices" — fall back to "text"/"options" for any + // older client or test that still uses the legacy field names. (Issue #206) + val text = + payload?.get("question") as? String + ?: payload?.get("text") as? String + val rawOptions = + payload?.get("choices") + ?: payload?.get("options") val clarifyId = payload?.get("clarify_id") as? String ?: payload?.get("request_id") as? String @Suppress("UNCHECKED_CAST") diff --git a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt index 623f290e..3a66760f 100644 --- a/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt +++ b/app/src/main/java/com/m57/hermescontrol/ui/chat/ChatScreen.kt @@ -842,7 +842,7 @@ private fun ClarifyDialog( onOptionSelected: (String) -> Unit, onDismiss: () -> Unit, ) { - var typedText by rememberSaveable(clarify.text) { mutableStateOf(clarify.text) } + var typedText by rememberSaveable(clarify.text) { mutableStateOf("") } AlertDialog( onDismissRequest = onDismiss, diff --git a/app/src/test/java/com/m57/hermescontrol/data/ws/EventParserTest.kt b/app/src/test/java/com/m57/hermescontrol/data/ws/EventParserTest.kt index 471a7cbe..92d40309 100644 --- a/app/src/test/java/com/m57/hermescontrol/data/ws/EventParserTest.kt +++ b/app/src/test/java/com/m57/hermescontrol/data/ws/EventParserTest.kt @@ -173,6 +173,32 @@ class EventParserTest { assertEquals(listOf("Yes", "No"), clarifyEvent.options) } + @Test + fun testParseClarifyRequest_withQuestionFields_parsesSuccessfully() { + val response = + JsonRpcResponse( + jsonrpc = "2.0", + id = null, + result = null, + error = null, + method = "event", + params = + mapOf( + "type" to "clarify.request", + "payload" to + mapOf( + "question" to "Which environment?", + "choices" to listOf("staging", "production"), + ), + ), + ) + val event = EventParser.parse(response) + assertTrue(event is WsEvent.ClarifyRequest) + val clarifyEvent = event as WsEvent.ClarifyRequest + assertEquals("Which environment?", clarifyEvent.text) + assertEquals(listOf("staging", "production"), clarifyEvent.options) + } + // ── TEST-07: Untested subtypes ───────────────────────────────────── @Test