* fix(#127): serialize tool event data to JSON for pretty formatting * fix(test): format tool start test case to satisfy ktlint
This commit is contained in:
2 files changed
+53
-2
No files matched your search
@@ -4,6 +4,7 @@ import android.app.Application
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.m57.hermescontrol.data.local.AuthManager
|
import com.m57.hermescontrol.data.local.AuthManager
|
||||||
import com.m57.hermescontrol.data.local.HermesDatabase
|
import com.m57.hermescontrol.data.local.HermesDatabase
|
||||||
import com.m57.hermescontrol.data.local.toEntity
|
import com.m57.hermescontrol.data.local.toEntity
|
||||||
@@ -371,10 +372,11 @@ class ChatViewModel(
|
|||||||
var orphanToPersist: ChatMessage? = null
|
var orphanToPersist: ChatMessage? = null
|
||||||
val sessionId = _uiState.value.currentSessionId
|
val sessionId = _uiState.value.currentSessionId
|
||||||
|
|
||||||
|
val contentJson = event.data?.let { Gson().toJson(it) } ?: ""
|
||||||
val toolMessage =
|
val toolMessage =
|
||||||
ChatMessage(
|
ChatMessage(
|
||||||
role = MessageRole.TOOL,
|
role = MessageRole.TOOL,
|
||||||
content = event.data.toString(),
|
content = contentJson,
|
||||||
toolName = event.name,
|
toolName = event.name,
|
||||||
toolStatus = ToolStatus.RUNNING,
|
toolStatus = ToolStatus.RUNNING,
|
||||||
)
|
)
|
||||||
@@ -418,10 +420,11 @@ class ChatViewModel(
|
|||||||
it.toolStatus == ToolStatus.RUNNING
|
it.toolStatus == ToolStatus.RUNNING
|
||||||
}
|
}
|
||||||
if (toolIdx >= 0) {
|
if (toolIdx >= 0) {
|
||||||
|
val contentJson = event.data?.let { Gson().toJson(it) } ?: ""
|
||||||
val updated =
|
val updated =
|
||||||
messages[toolIdx].copy(
|
messages[toolIdx].copy(
|
||||||
toolStatus = ToolStatus.COMPLETED,
|
toolStatus = ToolStatus.COMPLETED,
|
||||||
content = event.data.toString(),
|
content = contentJson,
|
||||||
)
|
)
|
||||||
messages[toolIdx] = updated
|
messages[toolIdx] = updated
|
||||||
completedTool = updated
|
completedTool = updated
|
||||||
|
|||||||
@@ -562,4 +562,52 @@ class ChatViewModelTest {
|
|||||||
assertEquals("Second response segment", state.streamingMessage?.content)
|
assertEquals("Second response segment", state.streamingMessage?.content)
|
||||||
assertTrue(state.streamingMessage?.isStreaming == true)
|
assertTrue(state.streamingMessage?.isStreaming == true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testToolExecution_serializesDataAsJson() =
|
||||||
|
runTest {
|
||||||
|
val viewModel = ChatViewModel(app, startCleanup = false)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
// Setup active session
|
||||||
|
var createReqId = ""
|
||||||
|
every { HermesWsClient.send(WsMethods.SESSION_CREATE, any(), any()) } answers {
|
||||||
|
createReqId = "create-req-tool-json-test"
|
||||||
|
val onSent = arg<((String) -> Unit)?>(2)
|
||||||
|
onSent?.invoke(createReqId)
|
||||||
|
createReqId
|
||||||
|
}
|
||||||
|
mockEventsFlow.emit(WsEvent.GatewayReady(null))
|
||||||
|
advanceUntilIdle()
|
||||||
|
mockEventsFlow.emit(WsEvent.RpcResult(createReqId, mapOf("session_id" to "session-123")))
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
// Start tool call
|
||||||
|
mockEventsFlow.emit(
|
||||||
|
WsEvent.ToolStart(
|
||||||
|
name = "calculator",
|
||||||
|
data =
|
||||||
|
mapOf(
|
||||||
|
"input" to "2+2",
|
||||||
|
"nested" to mapOf("key" to "value"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
var state = viewModel.uiState.value
|
||||||
|
assertEquals(2, state.messages.size)
|
||||||
|
assertEquals(MessageRole.TOOL, state.messages[1].role)
|
||||||
|
assertEquals("{\"input\":\"2+2\",\"nested\":{\"key\":\"value\"}}", state.messages[1].content)
|
||||||
|
assertEquals(ToolStatus.RUNNING, state.messages[1].toolStatus)
|
||||||
|
|
||||||
|
// Complete tool call
|
||||||
|
mockEventsFlow.emit(WsEvent.ToolComplete("calculator", mapOf("result" to "4", "exit_code" to 0)))
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
state = viewModel.uiState.value
|
||||||
|
assertEquals(2, state.messages.size)
|
||||||
|
assertEquals("{\"result\":\"4\",\"exit_code\":0}", state.messages[1].content)
|
||||||
|
assertEquals(ToolStatus.COMPLETED, state.messages[1].toolStatus)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user