feat(chat): live subagent steering and cancellation action sheet (closes #1030) (#1034)

Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-09-01 18:19:00 +03:00
1 parent 908255f5ad
commit 11dd1eff92
8 files changed
+414 -20

No files matched your search

@@ -3939,4 +3939,68 @@ class ChatViewModelTest {
.contains("Backend exploded"),
)
}
// ── Subagent steering & cancellation (issue #1030) ───────────────────
@Test
fun testSteerSubagent_sendsRedirectAndUpdatesStatus() =
runTest {
val (viewModel, sessionId) = createViewModelWithSession()
val indicator =
SubagentIndicator(
type = "subagent.start",
subagentId = "sub-123",
goal = "Search database",
status = "running",
)
mockEventsFlow.emit(
WsEvent.SubagentEvent(
type = "subagent.start",
payload = mapOf("subagent_id" to "sub-123", "goal" to "Search database"),
sessionId = sessionId,
),
)
advanceUntilIdle()
viewModel.steerSubagent(indicator, "Use index scan instead")
advanceUntilIdle()
val updated =
viewModel.uiState.value.subagentIndicators
.first { it.subagentId == "sub-123" }
assertEquals("steered", updated.status)
assertTrue(updated.logs.any { it.text.contains("Use index scan instead") })
io.mockk.verify { HermesWsClient.sendRedirect(sessionId, "/steer sub-123 Use index scan instead", any()) }
}
@Test
fun testStopSubagent_sendsRedirectAndMarksCancelled() =
runTest {
val (viewModel, sessionId) = createViewModelWithSession()
val indicator =
SubagentIndicator(
type = "subagent.start",
subagentId = "sub-123",
goal = "Run deep scan",
status = "running",
)
mockEventsFlow.emit(
WsEvent.SubagentEvent(
type = "subagent.start",
payload = mapOf("subagent_id" to "sub-123", "goal" to "Run deep scan"),
sessionId = sessionId,
),
)
advanceUntilIdle()
viewModel.stopSubagent(indicator)
advanceUntilIdle()
val updated =
viewModel.uiState.value.subagentIndicators
.first { it.subagentId == "sub-123" }
assertEquals("cancelled", updated.status)
assertTrue(updated.logs.any { it.text.contains("Stopped subagent") })
io.mockk.verify { HermesWsClient.sendRedirect(sessionId, "/stop sub-123", any()) }
}
}