From ff0477b88ad6f2d127a844f6675816b661054224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20Houl=C3=A9?= <13155277+tomhoule@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:28:20 +0100 Subject: [PATCH] agent_ui: Route agent thread feedback comments through cloud (#49481) The agent thread feedback comments event was still going through the standard telemetry pipeline. This routes it through cloud instead, as was just done for agent thread rated and edit prediction rated, so we can enforce organization data and privacy settings. Part of CLO-297 --- .../src/acp/thread_view/active_thread.rs | 26 +++++++++++------ .../cloud_api_client/src/cloud_api_client.rs | 28 +++++++++++++++++++ crates/cloud_api_types/src/cloud_api_types.rs | 9 ++++++ 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/crates/agent_ui/src/acp/thread_view/active_thread.rs b/crates/agent_ui/src/acp/thread_view/active_thread.rs index 904a42bfbecac8dc75de85d0e387edbec43174ef..7a399ce61b13b504c6408b5b78b51af97b0d8145 100644 --- a/crates/agent_ui/src/acp/thread_view/active_thread.rs +++ b/crates/agent_ui/src/acp/thread_view/active_thread.rs @@ -1,4 +1,4 @@ -use cloud_api_types::SubmitAgentThreadFeedbackBody; +use cloud_api_types::{SubmitAgentThreadFeedbackBody, SubmitAgentThreadFeedbackCommentsBody}; use gpui::{Corner, List}; use language_model::LanguageModelEffortLevel; use settings::update_settings_file; @@ -84,18 +84,28 @@ impl ThreadFeedbackState { self.comments_editor.take(); + let project = thread.read(cx).project().read(cx); + let client = project.client(); + let user_store = project.user_store(); + let organization = user_store.read(cx).current_organization(); + let session_id = thread.read(cx).session_id().clone(); let agent_telemetry_id = thread.read(cx).connection().telemetry_id(); let task = telemetry.thread_data(&session_id, cx); cx.background_spawn(async move { let thread = task.await?; - telemetry::event!( - "Agent Thread Feedback Comments", - agent = agent_telemetry_id, - session_id = session_id, - comments = comments, - thread = thread - ); + + client + .cloud_client() + .submit_agent_feedback_comments(SubmitAgentThreadFeedbackCommentsBody { + organization_id: organization.map(|organization| organization.id.clone()), + agent: agent_telemetry_id.to_string(), + session_id: session_id.to_string(), + comments, + thread, + }) + .await?; + anyhow::Ok(()) }) .detach_and_log_err(cx); diff --git a/crates/cloud_api_client/src/cloud_api_client.rs b/crates/cloud_api_client/src/cloud_api_client.rs index f0010a64cb95d35b56f35801b477a2fd6f665be1..35f34f5d436150b1bca641c425c0f9380bc0783b 100644 --- a/crates/cloud_api_client/src/cloud_api_client.rs +++ b/crates/cloud_api_client/src/cloud_api_client.rs @@ -207,6 +207,34 @@ impl CloudApiClient { Ok(()) } + pub async fn submit_agent_feedback_comments( + &self, + body: SubmitAgentThreadFeedbackCommentsBody, + ) -> Result<()> { + let request = self.build_request( + Request::builder().method(Method::POST).uri( + self.http_client + .build_zed_cloud_url("/client/feedback/agent_thread_comments")? + .as_ref(), + ), + AsyncBody::from(serde_json::to_string(&body)?), + )?; + + let mut response = self.http_client.send(request).await?; + + if !response.status().is_success() { + let mut body = String::new(); + response.body_mut().read_to_string(&mut body).await?; + + anyhow::bail!( + "Failed to submit agent feedback comments.\nStatus: {:?}\nBody: {body}", + response.status() + ) + } + + Ok(()) + } + pub async fn submit_edit_prediction_feedback( &self, body: SubmitEditPredictionFeedbackBody, diff --git a/crates/cloud_api_types/src/cloud_api_types.rs b/crates/cloud_api_types/src/cloud_api_types.rs index 2b9ec825e7df30fa64f21db1af7612930277798a..4b62405c8abd942f3ee1765319d1c1867ad43065 100644 --- a/crates/cloud_api_types/src/cloud_api_types.rs +++ b/crates/cloud_api_types/src/cloud_api_types.rs @@ -66,6 +66,15 @@ pub struct SubmitAgentThreadFeedbackBody { pub thread: serde_json::Value, } +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct SubmitAgentThreadFeedbackCommentsBody { + pub organization_id: Option, + pub agent: String, + pub session_id: String, + pub comments: String, + pub thread: serde_json::Value, +} + #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct SubmitEditPredictionFeedbackBody { pub organization_id: Option,