agent: Add telemetry events for subagents (#50849)
Katie Geer
created 1 month ago
Adds five telemetry events to track subagent lifecycle and user
interactions:
- **Subagent Started** — fires on creation or resumption, includes
parent session, subagent session, depth, and whether it was resumed
- **Subagent Completed** — fires when `SpawnAgentTool` finishes,
includes subagent session and status (completed/error)
- **Subagent Toggled** — fires when the user expands or collapses a
subagent card
- **Subagent Stopped** — fires when the user clicks Stop on a running
subagent
- **Subagent Maximized** — fires when the user clicks Maximize to
navigate into a subagent
Release Notes:
- N/A
Change summary
crates/agent/src/agent.rs | 22 ++++++++++++++++
crates/agent/src/tools/spawn_agent_tool.rs | 11 ++++++++
crates/agent_ui/src/connection_view/thread_view.rs | 5 +++
3 files changed, 38 insertions(+)
Detailed changes
@@ -1629,6 +1629,16 @@ impl NativeThreadEnvironment {
agent.register_session(subagent_thread.clone(), cx)
})?;
+ let depth = current_depth + 1;
+
+ telemetry::event!(
+ "Subagent Started",
+ session = parent_thread_entity.read(cx).id().to_string(),
+ subagent_session = session_id.to_string(),
+ depth,
+ is_resumed = false,
+ );
+
self.prompt_subagent(session_id, subagent_thread, acp_thread)
}
@@ -1645,6 +1655,18 @@ impl NativeThreadEnvironment {
anyhow::Ok((session.thread.clone(), session.acp_thread.clone()))
})??;
+ let depth = subagent_thread.read(cx).depth();
+
+ if let Some(parent_thread_entity) = self.thread.upgrade() {
+ telemetry::event!(
+ "Subagent Started",
+ session = parent_thread_entity.read(cx).id().to_string(),
+ subagent_session = session_id.to_string(),
+ depth,
+ is_resumed = true,
+ );
+ }
+
self.prompt_subagent(session_id, subagent_thread, acp_thread)
}
@@ -163,6 +163,17 @@ impl AgentTool for SpawnAgentTool {
let send_result = subagent.send(input.message, cx).await;
+ let status = if send_result.is_ok() {
+ "completed"
+ } else {
+ "error"
+ };
+ telemetry::event!(
+ "Subagent Completed",
+ subagent_session = session_info.session_id.to_string(),
+ status,
+ );
+
session_info.message_end_index =
cx.update(|cx| Some(subagent.num_entries(cx).saturating_sub(1)));
@@ -6756,6 +6756,9 @@ impl ThreadView {
this.expanded_tool_calls
.insert(tool_call_id.clone());
}
+ let expanded =
+ this.expanded_tool_calls.contains(&tool_call_id);
+ telemetry::event!("Subagent Toggled", expanded);
cx.notify();
}
}))
@@ -6774,6 +6777,7 @@ impl ThreadView {
|this, thread| {
this.on_click(cx.listener(
move |_this, _event, _window, cx| {
+ telemetry::event!("Subagent Stopped");
thread.update(cx, |thread, cx| {
thread.cancel(cx).detach();
});
@@ -6809,6 +6813,7 @@ impl ThreadView {
)
.tooltip(Tooltip::text("Make Subagent Full Screen"))
.on_click(cx.listener(move |this, _event, window, cx| {
+ telemetry::event!("Subagent Maximized");
this.server_view
.update(cx, |this, cx| {
this.navigate_to_session(session_id.clone(), window, cx);