Cargo.lock 🔗
@@ -6388,6 +6388,7 @@ dependencies = [
"serde_json",
"settings",
"supermaven",
+ "telemetry",
"theme",
"ui",
"workspace",
Agus Zubiaga created
Release Notes:
- N/A
Cargo.lock | 1
crates/editor/src/editor.rs | 14
crates/inline_completion_button/Cargo.toml | 1
crates/inline_completion_button/src/inline_completion_button.rs | 20 ++
crates/zed/src/zed/inline_completion_registry.rs | 19 +
crates/zeta/src/onboarding_banner.rs | 4
crates/zeta/src/onboarding_modal.rs | 26 ++
crates/zeta/src/onboarding_telemetry.rs | 9 +
crates/zeta/src/rate_completion_modal.rs | 2
crates/zeta/src/zeta.rs | 1
10 files changed, 82 insertions(+), 15 deletions(-)
@@ -6388,6 +6388,7 @@ dependencies = [
"serde_json",
"settings",
"supermaven",
+ "telemetry",
"theme",
"ui",
"workspace",
@@ -3946,10 +3946,6 @@ impl Editor {
self.do_completion(action.item_ix, CompletionIntent::Compose, window, cx)
}
- fn toggle_zed_predict_onboarding(&mut self, window: &mut Window, cx: &mut Context<Self>) {
- window.dispatch_action(zed_actions::OpenZedPredictOnboarding.boxed_clone(), cx);
- }
-
fn do_completion(
&mut self,
item_ix: Option<usize>,
@@ -5445,7 +5441,11 @@ impl Editor {
.on_mouse_down(MouseButton::Left, |_, window, _| window.prevent_default())
.on_click(cx.listener(|this, _event, window, cx| {
cx.stop_propagation();
- this.toggle_zed_predict_onboarding(window, cx)
+ this.report_editor_event("Edit Prediction Provider ToS Clicked", None, cx);
+ window.dispatch_action(
+ zed_actions::OpenZedPredictOnboarding.boxed_clone(),
+ cx,
+ );
}))
.child(
h_flex()
@@ -14074,7 +14074,8 @@ impl Editor {
.get("vim_mode")
== Some(&serde_json::Value::Bool(true));
- let copilot_enabled = all_language_settings(file, cx).inline_completions.provider
+ let edit_predictions_provider = all_language_settings(file, cx).inline_completions.provider;
+ let copilot_enabled = edit_predictions_provider
== language::language_settings::InlineCompletionProvider::Copilot;
let copilot_enabled_for_language = self
.buffer
@@ -14089,6 +14090,7 @@ impl Editor {
vim_mode,
copilot_enabled,
copilot_enabled_for_language,
+ edit_predictions_provider,
is_via_ssh = project.is_via_ssh(),
);
}
@@ -29,6 +29,7 @@ workspace.workspace = true
zed_actions.workspace = true
zeta.workspace = true
client.workspace = true
+telemetry.workspace = true
[dev-dependencies]
copilot = { workspace = true, features = ["test-support"] }
@@ -256,6 +256,10 @@ impl Render for InlineCompletionButton {
)
})
.on_click(cx.listener(move |_, _, window, cx| {
+ telemetry::event!(
+ "Pending ToS Clicked",
+ source = "Edit Prediction Status Button"
+ );
window.dispatch_action(
zed_actions::OpenZedPredictOnboarding.boxed_clone(),
cx,
@@ -426,6 +430,8 @@ impl InlineCompletionButton {
if data_collection.is_supported() {
let provider = provider.clone();
+ let enabled = data_collection.is_enabled();
+
menu = menu
.separator()
.header("Help Improve The Model")
@@ -434,9 +440,21 @@ impl InlineCompletionButton {
// TODO: We want to add something later that communicates whether
// the current project is open-source.
ContextMenuEntry::new("Share Training Data")
- .toggleable(IconPosition::Start, data_collection.is_enabled())
+ .toggleable(IconPosition::Start, enabled)
.handler(move |_, cx| {
provider.toggle_data_collection(cx);
+
+ if !enabled {
+ telemetry::event!(
+ "Data Collection Enabled",
+ source = "Edit Prediction Status Menu"
+ );
+ } else {
+ telemetry::event!(
+ "Data Collection Disabled",
+ source = "Edit Prediction Status Menu"
+ );
+ }
}),
);
}
@@ -94,7 +94,20 @@ pub fn init(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut App) {
let user_store = user_store.clone();
move |cx| {
let new_provider = all_language_settings(None, cx).inline_completions.provider;
+
if new_provider != provider {
+ let tos_accepted = user_store
+ .read(cx)
+ .current_user_has_accepted_terms()
+ .unwrap_or(false);
+
+ telemetry::event!(
+ "Edit Prediction Provider Changed",
+ from = provider,
+ to = new_provider,
+ zed_ai_tos_accepted = tos_accepted,
+ );
+
provider = new_provider;
assign_inline_completion_providers(
&editors,
@@ -104,11 +117,7 @@ pub fn init(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut App) {
cx,
);
- if !user_store
- .read(cx)
- .current_user_has_accepted_terms()
- .unwrap_or(false)
- {
+ if !tos_accepted {
match provider {
InlineCompletionProvider::Zed => {
let Some(window) = cx.active_window() else {
@@ -6,6 +6,8 @@ use settings::SettingsStore;
use ui::{prelude::*, ButtonLike, Tooltip};
use util::ResultExt;
+use crate::onboarding_event;
+
/// Prompts the user to try Zed's Edit Prediction feature
pub struct ZedPredictBanner {
dismissed: bool,
@@ -53,6 +55,7 @@ impl ZedPredictBanner {
}
fn dismiss(&mut self, cx: &mut Context<Self>) {
+ onboarding_event!("Banner Dismissed");
persist_dismissed(cx);
self.dismissed = true;
cx.notify();
@@ -107,6 +110,7 @@ impl Render for ZedPredictBanner {
),
)
.on_click(|_, window, cx| {
+ onboarding_event!("Banner Clicked");
window.dispatch_action(Box::new(zed_actions::OpenZedPredictOnboarding), cx)
}),
)
@@ -1,6 +1,6 @@
use std::{sync::Arc, time::Duration};
-use crate::ZED_PREDICT_DATA_COLLECTION_CHOICE;
+use crate::{onboarding_event, ZED_PREDICT_DATA_COLLECTION_CHOICE};
use client::{Client, UserStore};
use db::kvp::KEY_VALUE_STORE;
use feature_flags::FeatureFlagAppExt as _;
@@ -61,16 +61,22 @@ impl ZedPredictModal {
fn view_terms(&mut self, _: &ClickEvent, _: &mut Window, cx: &mut Context<Self>) {
cx.open_url("https://zed.dev/terms-of-service");
cx.notify();
+
+ onboarding_event!("ToS Link Clicked");
}
fn view_blog(&mut self, _: &ClickEvent, _: &mut Window, cx: &mut Context<Self>) {
cx.open_url("https://zed.dev/blog/"); // TODO Add the link when live
cx.notify();
+
+ onboarding_event!("Blog Link clicked");
}
fn inline_completions_doc(&mut self, _: &ClickEvent, _: &mut Window, cx: &mut Context<Self>) {
cx.open_url("https://zed.dev/docs/configuring-zed#inline-completions");
cx.notify();
+
+ onboarding_event!("Docs Link Clicked");
}
fn accept_and_enable(&mut self, _: &ClickEvent, window: &mut Window, cx: &mut Context<Self>) {
@@ -106,6 +112,11 @@ impl ZedPredictModal {
})
})
.detach_and_notify_err(window, cx);
+
+ onboarding_event!(
+ "Enable Clicked",
+ data_collection_opted_in = self.data_collection_opted_in,
+ );
}
fn sign_in(&mut self, _: &ClickEvent, window: &mut Window, cx: &mut Context<Self>) {
@@ -122,12 +133,15 @@ impl ZedPredictModal {
this.update(&mut cx, |this, cx| {
this.sign_in_status = status;
+ onboarding_event!("Signed In");
cx.notify()
})?;
result
})
.detach_and_notify_err(window, cx);
+
+ onboarding_event!("Sign In Clicked");
}
fn cancel(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
@@ -159,6 +173,7 @@ impl Render for ZedPredictModal {
.track_focus(&self.focus_handle(cx))
.on_action(cx.listener(Self::cancel))
.on_action(cx.listener(|_, _: &menu::Cancel, _window, cx| {
+ onboarding_event!("Cancelled", trigger = "Action");
cx.emit(DismissEvent);
}))
.on_any_mouse_down(cx.listener(|this, _: &MouseDownEvent, window, _cx| {
@@ -241,6 +256,7 @@ impl Render for ZedPredictModal {
.child(h_flex().absolute().top_2().right_2().child(
IconButton::new("cancel", IconName::X).on_click(cx.listener(
|_, _: &ClickEvent, _window, cx| {
+ onboarding_event!("Cancelled", trigger = "X click");
cx.emit(DismissEvent);
},
)),
@@ -302,7 +318,7 @@ impl Render for ZedPredictModal {
.label("Read and accept the")
.on_click(cx.listener(move |this, state, _window, cx| {
this.terms_of_service = *state == ToggleState::Selected;
- cx.notify()
+ cx.notify();
})),
)
.child(
@@ -340,7 +356,11 @@ impl Render for ZedPredictModal {
.on_click(cx.listener(|this, _, _, cx| {
this.data_collection_expanded =
!this.data_collection_expanded;
- cx.notify()
+ cx.notify();
+
+ if this.data_collection_expanded {
+ onboarding_event!("Data Collection Learn More Clicked");
+ }
})),
),
)
@@ -0,0 +1,9 @@
+#[macro_export]
+macro_rules! onboarding_event {
+ ($name:expr) => {
+ telemetry::event!($name, source = "Edit Prediction Onboarding");
+ };
+ ($name:expr, $($key:ident $(= $value:expr)?),+ $(,)?) => {
+ telemetry::event!($name, source = "Edit Prediction Onboarding", $($key $(= $value)?),+);
+ };
+}
@@ -52,6 +52,8 @@ impl RateCompletionModal {
pub fn toggle(workspace: &mut Workspace, window: &mut Window, cx: &mut Context<Workspace>) {
if let Some(zeta) = Zeta::global(cx) {
workspace.toggle_modal(window, cx, |_window, cx| RateCompletionModal::new(zeta, cx));
+
+ telemetry::event!("Rate Completion Modal Open", source = "Edit Prediction");
}
}
@@ -3,6 +3,7 @@ mod init;
mod license_detection;
mod onboarding_banner;
mod onboarding_modal;
+mod onboarding_telemetry;
mod rate_completion_modal;
pub(crate) use completion_diff_element::*;