Start separating authentication from connection to collab (#35471)
This pull request should be idempotent, but lays the groundwork for avoiding to connect to collab in order to interact with AI features provided by Zed. Release Notes: - N/A --------- Co-authored-by: Marshall Bowers <git@maxdeviant.com> Co-authored-by: Richard Feldman <oss@rtfeldman.com>
This commit is contained in:
parent
b01d1872cc
commit
f888f3fc0b
46 changed files with 653 additions and 855 deletions
|
@ -16,7 +16,7 @@ pub use rate_completion_modal::*;
|
|||
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use arrayvec::ArrayVec;
|
||||
use client::{Client, CloudUserStore, EditPredictionUsage};
|
||||
use client::{Client, EditPredictionUsage, UserStore};
|
||||
use cloud_llm_client::{
|
||||
AcceptEditPredictionBody, EXPIRED_LLM_TOKEN_HEADER_NAME, MINIMUM_REQUIRED_VERSION_HEADER_NAME,
|
||||
PredictEditsBody, PredictEditsResponse, ZED_VERSION_HEADER_NAME,
|
||||
|
@ -120,8 +120,8 @@ impl Dismissable for ZedPredictUpsell {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn should_show_upsell_modal(cloud_user_store: &Entity<CloudUserStore>, cx: &App) -> bool {
|
||||
if cloud_user_store.read(cx).has_accepted_tos() {
|
||||
pub fn should_show_upsell_modal(user_store: &Entity<UserStore>, cx: &App) -> bool {
|
||||
if user_store.read(cx).has_accepted_terms_of_service() {
|
||||
!ZedPredictUpsell::dismissed()
|
||||
} else {
|
||||
true
|
||||
|
@ -229,7 +229,7 @@ pub struct Zeta {
|
|||
_llm_token_subscription: Subscription,
|
||||
/// Whether an update to a newer version of Zed is required to continue using Zeta.
|
||||
update_required: bool,
|
||||
cloud_user_store: Entity<CloudUserStore>,
|
||||
user_store: Entity<UserStore>,
|
||||
license_detection_watchers: HashMap<WorktreeId, Rc<LicenseDetectionWatcher>>,
|
||||
}
|
||||
|
||||
|
@ -242,11 +242,11 @@ impl Zeta {
|
|||
workspace: Option<WeakEntity<Workspace>>,
|
||||
worktree: Option<Entity<Worktree>>,
|
||||
client: Arc<Client>,
|
||||
cloud_user_store: Entity<CloudUserStore>,
|
||||
user_store: Entity<UserStore>,
|
||||
cx: &mut App,
|
||||
) -> Entity<Self> {
|
||||
let this = Self::global(cx).unwrap_or_else(|| {
|
||||
let entity = cx.new(|cx| Self::new(workspace, client, cloud_user_store, cx));
|
||||
let entity = cx.new(|cx| Self::new(workspace, client, user_store, cx));
|
||||
cx.set_global(ZetaGlobal(entity.clone()));
|
||||
entity
|
||||
});
|
||||
|
@ -269,13 +269,13 @@ impl Zeta {
|
|||
}
|
||||
|
||||
pub fn usage(&self, cx: &App) -> Option<EditPredictionUsage> {
|
||||
self.cloud_user_store.read(cx).edit_prediction_usage()
|
||||
self.user_store.read(cx).edit_prediction_usage()
|
||||
}
|
||||
|
||||
fn new(
|
||||
workspace: Option<WeakEntity<Workspace>>,
|
||||
client: Arc<Client>,
|
||||
cloud_user_store: Entity<CloudUserStore>,
|
||||
user_store: Entity<UserStore>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let refresh_llm_token_listener = RefreshLlmTokenListener::global(cx);
|
||||
|
@ -306,7 +306,7 @@ impl Zeta {
|
|||
),
|
||||
update_required: false,
|
||||
license_detection_watchers: HashMap::default(),
|
||||
cloud_user_store,
|
||||
user_store,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,8 +535,8 @@ impl Zeta {
|
|||
|
||||
if let Some(usage) = usage {
|
||||
this.update(cx, |this, cx| {
|
||||
this.cloud_user_store.update(cx, |cloud_user_store, cx| {
|
||||
cloud_user_store.update_edit_prediction_usage(usage, cx);
|
||||
this.user_store.update(cx, |user_store, cx| {
|
||||
user_store.update_edit_prediction_usage(usage, cx);
|
||||
});
|
||||
})
|
||||
.ok();
|
||||
|
@ -877,8 +877,8 @@ and then another
|
|||
if response.status().is_success() {
|
||||
if let Some(usage) = EditPredictionUsage::from_headers(response.headers()).ok() {
|
||||
this.update(cx, |this, cx| {
|
||||
this.cloud_user_store.update(cx, |cloud_user_store, cx| {
|
||||
cloud_user_store.update_edit_prediction_usage(usage, cx);
|
||||
this.user_store.update(cx, |user_store, cx| {
|
||||
user_store.update_edit_prediction_usage(usage, cx);
|
||||
});
|
||||
})?;
|
||||
}
|
||||
|
@ -1559,9 +1559,9 @@ impl inline_completion::EditPredictionProvider for ZetaInlineCompletionProvider
|
|||
!self
|
||||
.zeta
|
||||
.read(cx)
|
||||
.cloud_user_store
|
||||
.user_store
|
||||
.read(cx)
|
||||
.has_accepted_tos()
|
||||
.has_accepted_terms_of_service()
|
||||
}
|
||||
|
||||
fn is_refreshing(&self) -> bool {
|
||||
|
@ -1587,7 +1587,7 @@ impl inline_completion::EditPredictionProvider for ZetaInlineCompletionProvider
|
|||
if self
|
||||
.zeta
|
||||
.read(cx)
|
||||
.cloud_user_store
|
||||
.user_store
|
||||
.read_with(cx, |cloud_user_store, _cx| {
|
||||
cloud_user_store.account_too_young() || cloud_user_store.has_overdue_invoices()
|
||||
})
|
||||
|
@ -1808,10 +1808,7 @@ mod tests {
|
|||
use client::UserStore;
|
||||
use client::test::FakeServer;
|
||||
use clock::FakeSystemClock;
|
||||
use cloud_api_types::{
|
||||
AuthenticatedUser, CreateLlmTokenResponse, GetAuthenticatedUserResponse, LlmToken, PlanInfo,
|
||||
};
|
||||
use cloud_llm_client::{CurrentUsage, Plan, UsageData, UsageLimit};
|
||||
use cloud_api_types::{CreateLlmTokenResponse, LlmToken};
|
||||
use gpui::TestAppContext;
|
||||
use http_client::FakeHttpClient;
|
||||
use indoc::indoc;
|
||||
|
@ -1820,39 +1817,6 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
|
||||
fn make_get_authenticated_user_response() -> GetAuthenticatedUserResponse {
|
||||
GetAuthenticatedUserResponse {
|
||||
user: AuthenticatedUser {
|
||||
id: 1,
|
||||
metrics_id: "metrics-id-1".to_string(),
|
||||
avatar_url: "".to_string(),
|
||||
github_login: "".to_string(),
|
||||
name: None,
|
||||
is_staff: false,
|
||||
accepted_tos_at: None,
|
||||
},
|
||||
feature_flags: vec![],
|
||||
plan: PlanInfo {
|
||||
plan: Plan::ZedPro,
|
||||
subscription_period: None,
|
||||
usage: CurrentUsage {
|
||||
model_requests: UsageData {
|
||||
used: 0,
|
||||
limit: UsageLimit::Limited(500),
|
||||
},
|
||||
edit_predictions: UsageData {
|
||||
used: 250,
|
||||
limit: UsageLimit::Unlimited,
|
||||
},
|
||||
},
|
||||
trial_started_at: None,
|
||||
is_usage_based_billing_enabled: false,
|
||||
is_account_too_young: false,
|
||||
has_overdue_invoices: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_inline_completion_basic_interpolation(cx: &mut TestAppContext) {
|
||||
let buffer = cx.new(|cx| Buffer::local("Lorem ipsum dolor", cx));
|
||||
|
@ -2054,14 +2018,6 @@ mod tests {
|
|||
|
||||
let http_client = FakeHttpClient::create(move |req| async move {
|
||||
match (req.method(), req.uri().path()) {
|
||||
(&Method::GET, "/client/users/me") => Ok(http_client::Response::builder()
|
||||
.status(200)
|
||||
.body(
|
||||
serde_json::to_string(&make_get_authenticated_user_response())
|
||||
.unwrap()
|
||||
.into(),
|
||||
)
|
||||
.unwrap()),
|
||||
(&Method::POST, "/client/llm_tokens") => Ok(http_client::Response::builder()
|
||||
.status(200)
|
||||
.body(
|
||||
|
@ -2098,9 +2054,7 @@ mod tests {
|
|||
// Construct the fake server to authenticate.
|
||||
let _server = FakeServer::for_client(42, &client, cx).await;
|
||||
let user_store = cx.new(|cx| UserStore::new(client.clone(), cx));
|
||||
let cloud_user_store =
|
||||
cx.new(|cx| CloudUserStore::new(client.cloud_client(), user_store.clone(), cx));
|
||||
let zeta = cx.new(|cx| Zeta::new(None, client, cloud_user_store, cx));
|
||||
let zeta = cx.new(|cx| Zeta::new(None, client, user_store.clone(), cx));
|
||||
|
||||
let buffer = cx.new(|cx| Buffer::local(buffer_content, cx));
|
||||
let cursor = buffer.read_with(cx, |buffer, _| buffer.anchor_before(Point::new(1, 0)));
|
||||
|
@ -2128,14 +2082,6 @@ mod tests {
|
|||
let completion = completion_response.clone();
|
||||
async move {
|
||||
match (req.method(), req.uri().path()) {
|
||||
(&Method::GET, "/client/users/me") => Ok(http_client::Response::builder()
|
||||
.status(200)
|
||||
.body(
|
||||
serde_json::to_string(&make_get_authenticated_user_response())
|
||||
.unwrap()
|
||||
.into(),
|
||||
)
|
||||
.unwrap()),
|
||||
(&Method::POST, "/client/llm_tokens") => Ok(http_client::Response::builder()
|
||||
.status(200)
|
||||
.body(
|
||||
|
@ -2172,9 +2118,7 @@ mod tests {
|
|||
// Construct the fake server to authenticate.
|
||||
let _server = FakeServer::for_client(42, &client, cx).await;
|
||||
let user_store = cx.new(|cx| UserStore::new(client.clone(), cx));
|
||||
let cloud_user_store =
|
||||
cx.new(|cx| CloudUserStore::new(client.cloud_client(), user_store.clone(), cx));
|
||||
let zeta = cx.new(|cx| Zeta::new(None, client, cloud_user_store, cx));
|
||||
let zeta = cx.new(|cx| Zeta::new(None, client, user_store.clone(), cx));
|
||||
|
||||
let buffer = cx.new(|cx| Buffer::local(buffer_content, cx));
|
||||
let snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue