feat(#538): wire tool.progress/generating + subagent.* events into chat (#567)

* feat(#538): wire tool.progress/generating + subagent.* events into chat

* fix(#538): remove subagent indicator on subagent.complete so it doesn't linger

* style(#538): drop dead Elvis on non-nullable event.text in onMessageComplete

---------

Co-authored-by: M57 <m57@hermes-control.app>
This commit is contained in:
M57andM57 authored and GitHub committed 2026-07-12 22:06:32 +03:00
1 parent 9e10c813d4
commit ee28ee5ce2
9 files changed
+592 -2

No files matched your search

@@ -90,6 +90,21 @@ object EventParser {
WsEvent.ToolComplete(name, payload, sessionId)
}
"tool.progress" -> {
val name = payload?.get("name") as? String
val preview = payload?.get("preview") as? String
WsEvent.ToolProgress(name, preview, sessionId)
}
"tool.generating" -> {
val name = payload?.get("name") as? String
WsEvent.ToolGenerating(name, sessionId)
}
"subagent.spawn_requested", "subagent.start", "subagent.progress", "subagent.complete" -> {
WsEvent.SubagentEvent(eventType, payload, sessionId)
}
"tool.output_risk" -> {
val toolId = payload?.get("tool_id") as? String ?: ""
val name = payload?.get("name") as? String ?: ""
@@ -79,6 +79,41 @@ sealed class WsEvent {
val sessionId: String? = null,
) : WsEvent()
/**
* Live tool execution progress with optional preview content.
*
* Events: `tool.progress`
* Payload: `{ name?: string, preview?: string }`
*/
data class ToolProgress(
val name: String? = null,
val preview: String? = null,
val sessionId: String? = null,
) : WsEvent()
/**
* Tool generation active state.
*
* Events: `tool.generating`
* Payload: `{ name?: string }`
*/
data class ToolGenerating(
val name: String? = null,
val sessionId: String? = null,
) : WsEvent()
/**
* Subagent execution and delegation events.
*
* Events: `subagent.spawn_requested`, `subagent.start`, `subagent.progress`, `subagent.complete`
* Payload includes goal, task_index, task_count, subagent_id, child_session_id, text, status, summary, duration_seconds.
*/
data class SubagentEvent(
val type: String,
val payload: Map<String, Any?>?,
val sessionId: String? = null,
) : WsEvent()
// ── Interactive ──────────────────────────────────────────────────────
data class ClarifyRequest(