feat(chat/activity): Self-improvement event badges for memory & skill updates (#744)

* feat(chat/activity): Self-improvement event badges for memory & skill updates (#737)

* feat(chat): Handle background review.summary WS events for self-improvement notices

---------

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-07-29 21:43:08 +03:00
1 parent 2cf41ead06
commit 1b596746af
12 files changed
+381 -1

No files matched your search

@@ -375,4 +375,27 @@ class ChatWsEventReducerTest {
assertEquals("Write tests", result.state.todos[0].content)
assertTrue(result.state.todos[0].isCompleted)
}
@Test
fun testReviewSummary_addsSystemMessage() {
val state = ChatUiState(currentSessionId = "session-1")
val event =
WsEvent.ReviewSummary(
text = "💾 Self-improvement review: Skill 'android-ci' patched",
sessionId = "session-1",
)
val result =
ChatWsEventReducer.reduce(
state = state,
streamingState = StreamingState(),
event = event,
currentSessionId = "session-1",
)
assertEquals(1, result.state.messages.size)
val msg = result.state.messages.first()
assertEquals(MessageRole.SYSTEM, msg.role)
assertEquals("💾 Self-improvement review: Skill 'android-ci' patched", msg.content)
}
}
@@ -319,4 +319,33 @@ class ToolBubbleParsingTest {
assertTrue(editDiff!!.contains("-val x = 1"))
assertTrue(editDiff.contains("+val x = 2"))
}
@Test
fun testParseSkillManage_createAndPatch() {
val createJson =
"""{
"tool_id": "call_sm_1",
"name": "skill_manage",
"args": {"action": "patch", "name": "our-workflow"},
"result": {"success": true, "message": "Patched skill our-workflow"}
}"""
val parsed = parseToolOutput(createJson, "skill_manage", false)
assertNotNull(parsed)
assertEquals("⚡ Skill Patched: our-workflow", parsed!!.summaryText)
assertEquals("✅ Patched skill our-workflow", parsed.mainOutput)
}
@Test
fun testParseMemory_selfImprovementBadge() {
val memJson =
"""{
"tool_id": "call_mem_1",
"name": "memory",
"args": {"action": "add", "target": "user"},
"result": {"success": true, "usage": "1,200 / 2,200 chars"}
}"""
val parsed = parseToolOutput(memJson, "memory", false)
assertNotNull(parsed)
assertEquals("🧠 Memory Saved (user)", parsed!!.summaryText)
}
}
@@ -48,4 +48,11 @@ class SystemViewModelTest {
viewModel.closeUpdateConfirm()
assertFalse(viewModel.uiState.value.updateConfirmOpen)
}
@Test
fun `initial uiState has null learningGraph`() {
val viewModel = SystemViewModel()
org.junit.Assert.assertNull(viewModel.uiState.value.learningGraph)
}
}