Differentiate between explicit rejection and ignored in ep acceptance tracking (#48409)

Closes #ISSUE

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Ben Kunkle authored and GitHub committed 2026-02-04 17:54:11 -05:00
1 parent 70f302cffa
commit d9959fb5cf
11 files changed
+46 -75

No files matched your search

@@ -173,6 +173,8 @@ pub enum EditPredictionRejectReason {
/// The current prediction was discarded
#[default]
Discarded,
/// The current prediction was explicitly rejected by the user
Rejected,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Serialize, Deserialize)]
+2 -2
View File
@@ -1,7 +1,7 @@
use anyhow::Result;
use edit_prediction::cursor_excerpt;
use edit_prediction_types::{
EditPrediction, EditPredictionDelegate, EditPredictionDismissReason, EditPredictionIconSet,
EditPrediction, EditPredictionDelegate, EditPredictionDiscardReason, EditPredictionIconSet,
};
use futures::AsyncReadExt;
use gpui::{App, Context, Entity, Task};
@@ -315,7 +315,7 @@ impl EditPredictionDelegate for CodestralEditPredictionDelegate {
self.current_completion = None;
}
fn discard(&mut self, _reason: EditPredictionDismissReason, _cx: &mut Context<Self>) {
fn discard(&mut self, _reason: EditPredictionDiscardReason, _cx: &mut Context<Self>) {
log::debug!("Codestral: Completion discarded");
self.pending_request = None;
self.current_completion = None;
@@ -7,7 +7,7 @@ use crate::{
};
use anyhow::Result;
use edit_prediction_types::{
EditPrediction, EditPredictionDelegate, EditPredictionDismissReason, EditPredictionIconSet,
EditPrediction, EditPredictionDelegate, EditPredictionDiscardReason, EditPredictionIconSet,
interpolate_edits,
};
use gpui::{App, Context, Entity, Task};
@@ -129,7 +129,7 @@ impl EditPredictionDelegate for CopilotEditPredictionDelegate {
}
}
fn discard(&mut self, _reason: EditPredictionDismissReason, _: &mut Context<Self>) {}
fn discard(&mut self, _reason: EditPredictionDiscardReason, _: &mut Context<Self>) {}
fn suggest(
&mut self,
+3 -20
View File
@@ -312,7 +312,6 @@ impl ProjectState {
prediction_id,
EditPredictionRejectReason::Canceled,
false,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
})
@@ -1293,19 +1292,12 @@ impl EditPredictionStore {
&mut self,
reason: EditPredictionRejectReason,
project: &Entity<Project>,
dismiss_reason: edit_prediction_types::EditPredictionDismissReason,
cx: &App,
) {
if let Some(project_state) = self.projects.get_mut(&project.entity_id()) {
project_state.pending_predictions.clear();
if let Some(prediction) = project_state.current_prediction.take() {
self.reject_prediction(
prediction.prediction.id,
reason,
prediction.was_shown,
dismiss_reason,
cx,
);
self.reject_prediction(prediction.prediction.id, reason, prediction.was_shown, cx);
}
};
}
@@ -1364,7 +1356,6 @@ impl EditPredictionStore {
prediction_id: EditPredictionId,
reason: EditPredictionRejectReason,
was_shown: bool,
dismiss_reason: edit_prediction_types::EditPredictionDismissReason,
cx: &App,
) {
match self.edit_prediction_model {
@@ -1384,7 +1375,7 @@ impl EditPredictionStore {
mercury::edit_prediction_rejected(
prediction_id,
was_shown,
dismiss_reason,
reason,
self.client.http_client(),
cx,
);
@@ -1638,7 +1629,6 @@ impl EditPredictionStore {
this.reject_current_prediction(
EditPredictionRejectReason::Replaced,
&project,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
@@ -1648,7 +1638,6 @@ impl EditPredictionStore {
new_prediction.prediction.id,
EditPredictionRejectReason::CurrentPreferred,
false,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
None
@@ -1658,13 +1647,7 @@ impl EditPredictionStore {
}
}
Err(reject_reason) => {
this.reject_prediction(
prediction_result.id,
reject_reason,
false,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
this.reject_prediction(prediction_result.id, reject_reason, false, cx);
None
}
}
@@ -94,12 +94,7 @@ async fn test_current_state(cx: &mut TestAppContext) {
});
ep_store.update(cx, |ep_store, cx| {
ep_store.reject_current_prediction(
EditPredictionRejectReason::Discarded,
&project,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
ep_store.reject_current_prediction(EditPredictionRejectReason::Discarded, &project, cx);
});
// Prediction for diagnostic in another file
@@ -1135,14 +1130,12 @@ async fn test_rejections_flushing(cx: &mut TestAppContext) {
EditPredictionId("test-1".into()),
EditPredictionRejectReason::Discarded,
false,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
ep_store.reject_prediction(
EditPredictionId("test-2".into()),
EditPredictionRejectReason::Canceled,
true,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
});
@@ -1179,7 +1172,6 @@ async fn test_rejections_flushing(cx: &mut TestAppContext) {
EditPredictionId(format!("batch-{}", i).into()),
EditPredictionRejectReason::Discarded,
false,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
}
@@ -1211,7 +1203,6 @@ async fn test_rejections_flushing(cx: &mut TestAppContext) {
EditPredictionId("retry-1".into()),
EditPredictionRejectReason::Discarded,
false,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
});
@@ -1231,7 +1222,6 @@ async fn test_rejections_flushing(cx: &mut TestAppContext) {
EditPredictionId("retry-2".into()),
EditPredictionRejectReason::Discarded,
false,
edit_prediction_types::EditPredictionDismissReason::Ignored,
cx,
);
});
+6 -5
View File
@@ -4,7 +4,7 @@ use crate::{
prediction::EditPredictionResult, zeta1::compute_edits,
};
use anyhow::{Context as _, Result};
use edit_prediction_types::EditPredictionDismissReason;
use cloud_llm_client::EditPredictionRejectReason;
use futures::AsyncReadExt as _;
use gpui::{
App, AppContext as _, Entity, Global, SharedString, Task,
@@ -358,16 +358,17 @@ pub(crate) fn edit_prediction_accepted(
pub(crate) fn edit_prediction_rejected(
prediction_id: EditPredictionId,
was_shown: bool,
dismiss_reason: EditPredictionDismissReason,
reason: EditPredictionRejectReason,
http_client: Arc<dyn HttpClient>,
cx: &App,
) {
if !was_shown {
return;
}
let action = match dismiss_reason {
EditPredictionDismissReason::Rejected => MercuryUserAction::Reject,
EditPredictionDismissReason::Ignored => MercuryUserAction::Ignore,
let action = match reason {
EditPredictionRejectReason::Rejected => MercuryUserAction::Reject,
EditPredictionRejectReason::Discarded => MercuryUserAction::Ignore,
_ => return,
};
send_feedback(prediction_id, action, http_client, cx);
}
@@ -3,7 +3,7 @@ use std::{cmp, sync::Arc};
use client::{Client, UserStore};
use cloud_llm_client::EditPredictionRejectReason;
use edit_prediction_types::{
DataCollectionState, EditPredictionDelegate, EditPredictionDismissReason,
DataCollectionState, EditPredictionDelegate, EditPredictionDiscardReason,
EditPredictionIconSet, SuggestionDisplayType,
};
use gpui::{App, Entity, prelude::*};
@@ -168,14 +168,13 @@ impl EditPredictionDelegate for ZedEditPredictionDelegate {
});
}
fn discard(&mut self, reason: EditPredictionDismissReason, cx: &mut Context<Self>) {
fn discard(&mut self, reason: EditPredictionDiscardReason, cx: &mut Context<Self>) {
let reject_reason = match reason {
EditPredictionDiscardReason::Rejected => EditPredictionRejectReason::Rejected,
EditPredictionDiscardReason::Ignored => EditPredictionRejectReason::Discarded,
};
self.store.update(cx, |store, cx| {
store.reject_current_prediction(
EditPredictionRejectReason::Discarded,
&self.project,
reason,
cx,
);
store.reject_current_prediction(reject_reason, &self.project, cx);
});
}
@@ -213,7 +212,6 @@ impl EditPredictionDelegate for ZedEditPredictionDelegate {
store.reject_current_prediction(
EditPredictionRejectReason::InterpolatedEmpty,
&self.project,
EditPredictionDismissReason::Ignored,
cx,
);
return None;
@@ -4,7 +4,7 @@ use client::EditPredictionUsage;
use gpui::{App, Context, Entity, SharedString};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EditPredictionDismissReason {
pub enum EditPredictionDiscardReason {
Rejected,
Ignored,
}
@@ -184,7 +184,7 @@ pub trait EditPredictionDelegate: 'static + Sized {
cx: &mut Context<Self>,
);
fn accept(&mut self, cx: &mut Context<Self>);
fn discard(&mut self, reason: EditPredictionDismissReason, cx: &mut Context<Self>);
fn discard(&mut self, reason: EditPredictionDiscardReason, cx: &mut Context<Self>);
fn did_show(&mut self, _display_type: SuggestionDisplayType, _cx: &mut Context<Self>) {}
fn suggest(
&mut self,
@@ -220,7 +220,7 @@ pub trait EditPredictionDelegateHandle {
);
fn did_show(&self, display_type: SuggestionDisplayType, cx: &mut App);
fn accept(&self, cx: &mut App);
fn discard(&self, reason: EditPredictionDismissReason, cx: &mut App);
fn discard(&self, reason: EditPredictionDiscardReason, cx: &mut App);
fn suggest(
&self,
buffer: &Entity<Buffer>,
@@ -298,7 +298,7 @@ where
self.update(cx, |this, cx| this.accept(cx))
}
fn discard(&self, reason: EditPredictionDismissReason, cx: &mut App) {
fn discard(&self, reason: EditPredictionDiscardReason, cx: &mut App) {
self.update(cx, |this, cx| this.discard(reason, cx))
}
+2 -2
View File
@@ -625,7 +625,7 @@ impl EditPredictionDelegate for FakeEditPredictionDelegate {
fn discard(
&mut self,
_reason: edit_prediction_types::EditPredictionDismissReason,
_reason: edit_prediction_types::EditPredictionDiscardReason,
_cx: &mut gpui::Context<Self>,
) {
}
@@ -701,7 +701,7 @@ impl EditPredictionDelegate for FakeNonZedEditPredictionDelegate {
fn discard(
&mut self,
_reason: edit_prediction_types::EditPredictionDismissReason,
_reason: edit_prediction_types::EditPredictionDiscardReason,
_cx: &mut gpui::Context<Self>,
) {
}
+15 -18
View File
@@ -96,7 +96,7 @@ use convert_case::{Case, Casing};
use dap::TelemetrySpawnLocation;
use display_map::*;
use edit_prediction_types::{
EditPredictionDelegate, EditPredictionDelegateHandle, EditPredictionDismissReason,
EditPredictionDelegate, EditPredictionDelegateHandle, EditPredictionDiscardReason,
EditPredictionGranularity, SuggestionDisplayType,
};
use editor_settings::{GoToDefinitionFallback, Minimap as MinimapSettings};
@@ -3406,7 +3406,7 @@ impl Editor {
self.update_edit_prediction_settings(cx);
if let Some(false) = show_edit_predictions {
self.discard_edit_prediction(false, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
} else {
self.refresh_edit_prediction(false, true, window, cx);
}
@@ -4438,7 +4438,8 @@ impl Editor {
dismissed |= self.hide_signature_help(cx, SignatureHelpHiddenBy::Escape);
dismissed |= self.hide_context_menu(window, cx).is_some();
dismissed |= self.mouse_context_menu.take().is_some();
dismissed |= is_user_requested && self.discard_edit_prediction(true, cx);
dismissed |= is_user_requested
&& self.discard_edit_prediction(EditPredictionDiscardReason::Rejected, cx);
dismissed |= self.snippet_stack.pop().is_some();
if self.diff_review_drag_state.is_some() {
self.cancel_diff_review_drag(cx);
@@ -6190,7 +6191,8 @@ impl Editor {
if editor.show_edit_predictions_in_menu() {
editor.update_visible_edit_prediction(window, cx);
} else {
editor.discard_edit_prediction(false, cx);
editor
.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
}
cx.notify();
@@ -6297,7 +6299,7 @@ impl Editor {
let entries = completions_menu.entries.borrow();
let mat = entries.get(item_ix.unwrap_or(completions_menu.selected_item))?;
if self.show_edit_predictions_in_menu() {
self.discard_edit_prediction(true, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Rejected, cx);
}
mat.candidate_id
};
@@ -6552,7 +6554,7 @@ impl Editor {
let deployed_from = action.deployed_from.clone();
let action = action.clone();
self.completion_tasks.clear();
self.discard_edit_prediction(false, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
let multibuffer_point = match &action.deployed_from {
Some(CodeActionSource::Indicator(row)) | Some(CodeActionSource::RunMenu(row)) => {
@@ -7653,7 +7655,7 @@ impl Editor {
self.buffer.read(cx).text_anchor_for_position(cursor, cx)?;
if !self.edit_predictions_enabled_in_buffer(&buffer, cursor_buffer_position, cx) {
self.discard_edit_prediction(false, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
return None;
}
@@ -7664,7 +7666,7 @@ impl Editor {
|| !self.is_focused(window)
|| buffer.read(cx).is_empty())
{
self.discard_edit_prediction(false, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
return None;
}
@@ -7699,7 +7701,7 @@ impl Editor {
pub fn update_edit_prediction_settings(&mut self, cx: &mut Context<Self>) {
if self.edit_prediction_provider.is_none() || DisableAiSettings::get_global(cx).disable_ai {
self.edit_prediction_settings = EditPredictionSettings::Disabled;
self.discard_edit_prediction(false, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
} else {
let selection = self.selections.newest_anchor();
let cursor = selection.head();
@@ -8073,10 +8075,10 @@ impl Editor {
fn discard_edit_prediction(
&mut self,
should_report_edit_prediction_event: bool,
reason: EditPredictionDiscardReason,
cx: &mut Context<Self>,
) -> bool {
if should_report_edit_prediction_event {
if reason == EditPredictionDiscardReason::Rejected {
let completion_id = self
.active_edit_prediction
.as_ref()
@@ -8086,11 +8088,6 @@ impl Editor {
}
if let Some(provider) = self.edit_prediction_provider() {
let reason = if should_report_edit_prediction_event {
EditPredictionDismissReason::Rejected
} else {
EditPredictionDismissReason::Ignored
};
provider.discard(reason, cx);
}
@@ -8360,7 +8357,7 @@ impl Editor {
}
if self.ime_transaction.is_some() {
self.discard_edit_prediction(false, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
return None;
}
@@ -8389,7 +8386,7 @@ impl Editor {
!invalidation_range.contains(&offset_selection.head())
})
{
self.discard_edit_prediction(false, cx);
self.discard_edit_prediction(EditPredictionDiscardReason::Ignored, cx);
return None;
}
@@ -1,7 +1,7 @@
use crate::{Supermaven, SupermavenCompletionStateId};
use anyhow::Result;
use edit_prediction_types::{
EditPrediction, EditPredictionDelegate, EditPredictionDismissReason, EditPredictionIconSet,
EditPrediction, EditPredictionDelegate, EditPredictionDiscardReason, EditPredictionIconSet,
};
use futures::StreamExt as _;
use gpui::{App, Context, Entity, EntityId, Task};
@@ -203,7 +203,7 @@ impl EditPredictionDelegate for SupermavenEditPredictionDelegate {
reset_completion_cache(self, _cx);
}
fn discard(&mut self, _reason: EditPredictionDismissReason, _cx: &mut Context<Self>) {
fn discard(&mut self, _reason: EditPredictionDiscardReason, _cx: &mut Context<Self>) {
reset_completion_cache(self, _cx);
}