fn render(ui: &Ui, thread: ThreadId, event: Event) {
let nested = event.turn_info.as_ref().is_some_and(|t| t.parent_tool_id.is_some());
match event.kind {
// content
EventKind::TextDelta { message_id, text } if !nested => ui.append(thread, message_id, text),
EventKind::ReasoningDelta { text, .. } if !nested => ui.append_thinking(thread, text),
EventKind::MessageEnded { message_id } => ui.finish_message(thread, message_id),
// tools: ToolUpdated is a full snapshot, replace by id
EventKind::ToolUpdated(tool) => ui.upsert_tool(thread, event.turn_info, tool),
EventKind::ToolOutputDelta { tool_id, text } => ui.append_tool_output(thread, tool_id, text),
EventKind::PlanUpdated { entries } => ui.set_plan(thread, entries), // replaces, not appends
// requests: step 6
EventKind::RequestOpened(request) => ui.open_request(thread, request),
EventKind::RequestClosed { request_id } => ui.close_request(thread, request_id),
// session state
EventKind::StatusChanged(status) => ui.set_badge(thread, status),
EventKind::SessionUpdated(info) => { store.save_info(thread, &info); ui.rebuild_settings(thread, &info) }
EventKind::ContextUsage { used_tokens, window_tokens, .. } => ui.set_gauge(thread, used_tokens, window_tokens),
// turn boundaries
EventKind::TurnStarted { .. } => ui.start_turn(thread),
EventKind::TurnEnded { stop, background } => ui.end_turn(thread, stop, background),
EventKind::Diagnostic(d) => tracing::warn!(?d),
_ => {}
}
}