This commit is contained in:
9 files changed
+179
-42
No files matched your search
@@ -980,7 +980,12 @@ class EventParserTest {
|
||||
mapOf(
|
||||
"type" to "tool.progress",
|
||||
"session_id" to "sess-123",
|
||||
"payload" to mapOf("name" to "web_search", "preview" to "downloading content..."),
|
||||
"payload" to
|
||||
mapOf(
|
||||
"tool_id" to "call-progress",
|
||||
"name" to "web_search",
|
||||
"preview" to "downloading content...",
|
||||
),
|
||||
),
|
||||
)
|
||||
val event = EventParser.parse(response)
|
||||
@@ -989,6 +994,7 @@ class EventParserTest {
|
||||
assertEquals("web_search", toolProgress.name)
|
||||
assertEquals("downloading content...", toolProgress.preview)
|
||||
assertEquals("sess-123", toolProgress.sessionId)
|
||||
assertEquals("call-progress", toolProgress.toolId)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1004,7 +1010,7 @@ class EventParserTest {
|
||||
mapOf(
|
||||
"type" to "tool.generating",
|
||||
"session_id" to "sess-123",
|
||||
"payload" to mapOf("name" to "code_writer"),
|
||||
"payload" to mapOf("tool_id" to "call-generating", "name" to "code_writer"),
|
||||
),
|
||||
)
|
||||
val event = EventParser.parse(response)
|
||||
@@ -1012,6 +1018,7 @@ class EventParserTest {
|
||||
val toolGenerating = event as WsEvent.ToolGenerating
|
||||
assertEquals("code_writer", toolGenerating.name)
|
||||
assertEquals("sess-123", toolGenerating.sessionId)
|
||||
assertEquals("call-generating", toolGenerating.toolId)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -509,6 +509,103 @@ class ChatWsEventReducerTest {
|
||||
assertTrue(result.state.todos[1].isInProgress)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testToolLifecycle_sameNameUsesToolIdForProgressAndCompletion() {
|
||||
val state = ChatUiState(currentSessionId = "session-1")
|
||||
val first =
|
||||
ChatWsEventReducer.reduce(
|
||||
state,
|
||||
StreamingState(),
|
||||
WsEvent.ToolStart(
|
||||
name = "process_manage",
|
||||
data = mapOf("tool_id" to "call-1", "action" to "wait"),
|
||||
sessionId = "session-1",
|
||||
),
|
||||
"session-1",
|
||||
)
|
||||
val second =
|
||||
ChatWsEventReducer.reduce(
|
||||
first.state,
|
||||
first.streamingState,
|
||||
WsEvent.ToolStart(
|
||||
name = "process_manage",
|
||||
data = mapOf("tool_id" to "call-2", "action" to "wait"),
|
||||
sessionId = "session-1",
|
||||
),
|
||||
"session-1",
|
||||
)
|
||||
|
||||
val progress =
|
||||
ChatWsEventReducer.reduce(
|
||||
second.state,
|
||||
second.streamingState,
|
||||
WsEvent.ToolProgress(
|
||||
name = "process_manage",
|
||||
preview = "call-1 is still waiting",
|
||||
sessionId = "session-1",
|
||||
toolId = "call-1",
|
||||
),
|
||||
"session-1",
|
||||
)
|
||||
assertEquals("call-1 is still waiting", progress.state.messages[0].progressPreview)
|
||||
assertNull(progress.state.messages[1].progressPreview)
|
||||
|
||||
val completed =
|
||||
ChatWsEventReducer.reduce(
|
||||
progress.state,
|
||||
progress.streamingState,
|
||||
WsEvent.ToolComplete(
|
||||
name = "process_manage",
|
||||
data = mapOf("tool_id" to "call-1", "output" to "finished"),
|
||||
sessionId = "session-1",
|
||||
),
|
||||
"session-1",
|
||||
)
|
||||
assertEquals(ToolStatus.COMPLETED, completed.state.messages[0].toolStatus)
|
||||
assertEquals(ToolStatus.RUNNING, completed.state.messages[1].toolStatus)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testToolOutputRisk_sameNameUsesToolId() {
|
||||
val state = ChatUiState(currentSessionId = "session-1")
|
||||
val first =
|
||||
ChatWsEventReducer.reduce(
|
||||
state,
|
||||
StreamingState(),
|
||||
WsEvent.ToolStart("terminal", mapOf("tool_id" to "call-1"), "session-1"),
|
||||
"session-1",
|
||||
)
|
||||
val second =
|
||||
ChatWsEventReducer.reduce(
|
||||
first.state,
|
||||
first.streamingState,
|
||||
WsEvent.ToolStart("terminal", mapOf("tool_id" to "call-2"), "session-1"),
|
||||
"session-1",
|
||||
)
|
||||
|
||||
val result =
|
||||
ChatWsEventReducer.reduce(
|
||||
second.state,
|
||||
second.streamingState,
|
||||
WsEvent.ToolOutputRisk(
|
||||
toolId = "call-1",
|
||||
name = "terminal",
|
||||
risk = "high",
|
||||
findings = listOf("secret"),
|
||||
sessionId = "session-1",
|
||||
),
|
||||
"session-1",
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
"high",
|
||||
result.state.messages[0]
|
||||
.toolOutputRiskData
|
||||
?.risk,
|
||||
)
|
||||
assertNull(result.state.messages[1].toolOutputRiskData)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHydrateTodosFromMessages_parsesStoredToolMessage() {
|
||||
val todoMessage =
|
||||
|
||||
@@ -281,6 +281,21 @@ class ToolViewBuilderTest {
|
||||
assertTrue(view.detail.contains("sleep 100"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `running process_manage shows pending detail instead of completion`() {
|
||||
val view =
|
||||
build(
|
||||
"process_manage",
|
||||
"""{"action":"wait","session_id":"proc-1"}""",
|
||||
"""{"tool_id":"call-1","name":"process_manage","args":{"action":"wait"}}""",
|
||||
running = true,
|
||||
)
|
||||
|
||||
assertEquals(ToolViewStatus.RUNNING, view.status)
|
||||
assertEquals("⏳ wait in progress", view.detail)
|
||||
assertFalse(view.detail.contains("done"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `todo_list alias activates TodoRenderer`() {
|
||||
val view =
|
||||
|
||||
Reference in new issue
Block a user