From f05d756913c66e05eeb83343b847a2799b926e41 Mon Sep 17 00:00:00 2001 From: Katie Geer Date: Thu, 5 Mar 2026 12:46:53 -0800 Subject: [PATCH] agent: Add telemetry events for subagents (#50849) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- crates/agent/src/agent.rs | 22 +++++++++++++++++++ crates/agent/src/tools/spawn_agent_tool.rs | 11 ++++++++++ .../src/connection_view/thread_view.rs | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/crates/agent/src/agent.rs b/crates/agent/src/agent.rs index 77c7ab02eb9e61a270c2e5679a6972fc817e0ce0..a93c2d2062b7472f8ed94a6ea0947a685edd204f 100644 --- a/crates/agent/src/agent.rs +++ b/crates/agent/src/agent.rs @@ -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) } diff --git a/crates/agent/src/tools/spawn_agent_tool.rs b/crates/agent/src/tools/spawn_agent_tool.rs index 162de68b86115056e9579d22a8623d675245cc91..9c10b2fbf127c42d842300f4af865c4297cdedb8 100644 --- a/crates/agent/src/tools/spawn_agent_tool.rs +++ b/crates/agent/src/tools/spawn_agent_tool.rs @@ -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))); diff --git a/crates/agent_ui/src/connection_view/thread_view.rs b/crates/agent_ui/src/connection_view/thread_view.rs index af8675f9466bf2ee4372f15978db1f76804e8971..abf5ba5b8f9941811de3a7454f2cb38a4ed72b22 100644 --- a/crates/agent_ui/src/connection_view/thread_view.rs +++ b/crates/agent_ui/src/connection_view/thread_view.rs @@ -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);