zeta: Do not show usage for copilot/supermaven (#30563)

Follow up to #29952

Release Notes:

- Fix an issue where zeta usage would show up when using Copilot as an
edit prediction provider
This commit is contained in:
Bennet Bo Fenner 2025-05-12 16:03:50 +02:00 committed by GitHub
parent 8e39281699
commit 19b6c4444e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 64 additions and 64 deletions

2
Cargo.lock generated
View file

@ -7225,7 +7225,6 @@ dependencies = [
"lsp", "lsp",
"paths", "paths",
"project", "project",
"proto",
"regex", "regex",
"serde_json", "serde_json",
"settings", "settings",
@ -7233,7 +7232,6 @@ dependencies = [
"telemetry", "telemetry",
"theme", "theme",
"ui", "ui",
"util",
"workspace", "workspace",
"workspace-hack", "workspace-hack",
"zed_actions", "zed_actions",

View file

@ -24,13 +24,11 @@ indoc.workspace = true
inline_completion.workspace = true inline_completion.workspace = true
language.workspace = true language.workspace = true
paths.workspace = true paths.workspace = true
proto.workspace = true
regex.workspace = true regex.workspace = true
settings.workspace = true settings.workspace = true
supermaven.workspace = true supermaven.workspace = true
telemetry.workspace = true telemetry.workspace = true
ui.workspace = true ui.workspace = true
util.workspace = true
workspace-hack.workspace = true workspace-hack.workspace = true
workspace.workspace = true workspace.workspace = true
zed_actions.workspace = true zed_actions.workspace = true

View file

@ -14,7 +14,6 @@ use gpui::{
pulsating_between, pulsating_between,
}; };
use indoc::indoc; use indoc::indoc;
use inline_completion::EditPredictionUsage;
use language::{ use language::{
EditPredictionsMode, File, Language, EditPredictionsMode, File, Language,
language_settings::{self, AllLanguageSettings, EditPredictionProvider, all_language_settings}, language_settings::{self, AllLanguageSettings, EditPredictionProvider, all_language_settings},
@ -30,7 +29,6 @@ use ui::{
Clickable, ContextMenu, ContextMenuEntry, DocumentationSide, IconButton, IconButtonShape, Clickable, ContextMenu, ContextMenuEntry, DocumentationSide, IconButton, IconButtonShape,
Indicator, PopoverMenu, PopoverMenuHandle, ProgressBar, Tooltip, prelude::*, Indicator, PopoverMenu, PopoverMenuHandle, ProgressBar, Tooltip, prelude::*,
}; };
use util::maybe;
use workspace::{ use workspace::{
StatusItemView, Toast, Workspace, create_and_open_local_file, item::ItemHandle, StatusItemView, Toast, Workspace, create_and_open_local_file, item::ItemHandle,
notifications::NotificationId, notifications::NotificationId,
@ -405,64 +403,44 @@ impl InlineCompletionButton {
let fs = self.fs.clone(); let fs = self.fs.clone();
let line_height = window.line_height(); let line_height = window.line_height();
if let Some(provider) = self.edit_prediction_provider.as_ref() { if let Some(usage) = self
let usage = provider.usage(cx).or_else(|| { .edit_prediction_provider
let user_store = self.user_store.read(cx); .as_ref()
.and_then(|provider| provider.usage(cx))
maybe!({ {
let amount = user_store.edit_predictions_usage_amount()?; menu = menu.header("Usage");
let limit = user_store.edit_predictions_usage_limit()?.variant?; menu = menu
.custom_entry(
Some(EditPredictionUsage { move |_window, cx| {
amount: amount as i32, let used_percentage = match usage.limit {
limit: match limit { UsageLimit::Limited(limit) => {
proto::usage_limit::Variant::Limited(limited) => { Some((usage.amount as f32 / limit as f32) * 100.)
zed_llm_client::UsageLimit::Limited(limited.limit as i32)
} }
proto::usage_limit::Variant::Unlimited(_) => { UsageLimit::Unlimited => None,
zed_llm_client::UsageLimit::Unlimited };
}
},
})
})
});
if let Some(usage) = usage { h_flex()
menu = menu.header("Usage"); .flex_1()
menu = menu .gap_1p5()
.custom_entry( .children(
move |_window, cx| { used_percentage
let used_percentage = match usage.limit { .map(|percent| ProgressBar::new("usage", percent, 100., cx)),
UsageLimit::Limited(limit) => { )
Some((usage.amount as f32 / limit as f32) * 100.) .child(
} Label::new(match usage.limit {
UsageLimit::Unlimited => None, UsageLimit::Limited(limit) => {
}; format!("{} / {limit}", usage.amount)
}
h_flex() UsageLimit::Unlimited => format!("{} / ∞", usage.amount),
.flex_1() })
.gap_1p5() .size(LabelSize::Small)
.children( .color(Color::Muted),
used_percentage.map(|percent| { )
ProgressBar::new("usage", percent, 100., cx) .into_any_element()
}), },
) move |_, cx| cx.open_url(&zed_urls::account_url(cx)),
.child( )
Label::new(match usage.limit { .separator();
UsageLimit::Limited(limit) => {
format!("{} / {limit}", usage.amount)
}
UsageLimit::Unlimited => format!("{} / ∞", usage.amount),
})
.size(LabelSize::Small)
.color(Color::Muted),
)
.into_any_element()
},
move |_, cx| cx.open_url(&zed_urls::account_url(cx)),
)
.separator();
}
} }
menu = menu.header("Show Edit Predictions For"); menu = menu.header("Show Edit Predictions For");

View file

@ -48,7 +48,7 @@ use std::{
}; };
use telemetry_events::InlineCompletionRating; use telemetry_events::InlineCompletionRating;
use thiserror::Error; use thiserror::Error;
use util::ResultExt; use util::{ResultExt, maybe};
use uuid::Uuid; use uuid::Uuid;
use workspace::Workspace; use workspace::Workspace;
use workspace::notifications::{ErrorMessagePrompt, NotificationId}; use workspace::notifications::{ErrorMessagePrompt, NotificationId};
@ -193,6 +193,7 @@ pub struct Zeta {
tos_accepted: bool, tos_accepted: bool,
/// Whether an update to a newer version of Zed is required to continue using Zeta. /// Whether an update to a newer version of Zed is required to continue using Zeta.
update_required: bool, update_required: bool,
user_store: Entity<UserStore>,
_user_store_subscription: Subscription, _user_store_subscription: Subscription,
license_detection_watchers: HashMap<WorktreeId, Rc<LicenseDetectionWatcher>>, license_detection_watchers: HashMap<WorktreeId, Rc<LicenseDetectionWatcher>>,
} }
@ -232,6 +233,28 @@ impl Zeta {
self.events.clear(); self.events.clear();
} }
pub fn usage(&self, cx: &App) -> Option<EditPredictionUsage> {
self.last_usage.or_else(|| {
let user_store = self.user_store.read(cx);
maybe!({
let amount = user_store.edit_predictions_usage_amount()?;
let limit = user_store.edit_predictions_usage_limit()?.variant?;
Some(EditPredictionUsage {
amount: amount as i32,
limit: match limit {
proto::usage_limit::Variant::Limited(limited) => {
zed_llm_client::UsageLimit::Limited(limited.limit as i32)
}
proto::usage_limit::Variant::Unlimited(_) => {
zed_llm_client::UsageLimit::Unlimited
}
},
})
})
})
}
fn new( fn new(
workspace: Option<WeakEntity<Workspace>>, workspace: Option<WeakEntity<Workspace>>,
client: Arc<Client>, client: Arc<Client>,
@ -282,6 +305,7 @@ impl Zeta {
} }
}), }),
license_detection_watchers: HashMap::default(), license_detection_watchers: HashMap::default(),
user_store,
} }
} }
@ -1417,7 +1441,7 @@ impl inline_completion::EditPredictionProvider for ZetaInlineCompletionProvider
} }
fn usage(&self, cx: &App) -> Option<EditPredictionUsage> { fn usage(&self, cx: &App) -> Option<EditPredictionUsage> {
self.zeta.read(cx).last_usage self.zeta.read(cx).usage(cx)
} }
fn is_enabled( fn is_enabled(
@ -1891,6 +1915,7 @@ mod tests {
zeta.request_completion(None, &buffer, cursor, false, cx) zeta.request_completion(None, &buffer, cursor, false, cx)
}); });
server.receive::<proto::GetUsers>().await.unwrap();
let token_request = server.receive::<proto::GetLlmToken>().await.unwrap(); let token_request = server.receive::<proto::GetLlmToken>().await.unwrap();
server.respond( server.respond(
token_request.receipt(), token_request.receipt(),
@ -1945,6 +1970,7 @@ mod tests {
zeta.request_completion(None, &buffer, cursor, false, cx) zeta.request_completion(None, &buffer, cursor, false, cx)
}); });
server.receive::<proto::GetUsers>().await.unwrap();
let token_request = server.receive::<proto::GetLlmToken>().await.unwrap(); let token_request = server.receive::<proto::GetLlmToken>().await.unwrap();
server.respond( server.respond(
token_request.receipt(), token_request.receipt(),