Remove `billing-v2` feature flag (#38843)

Marshall Bowers created

This PR removes the `billing-v2` feature flag, now that the new pricing
is launched.

Release Notes:

- N/A

Change summary

Cargo.lock                                       |  2 -
crates/ai_onboarding/Cargo.toml                  |  1 
crates/ai_onboarding/src/ai_onboarding.rs        |  9 +++----
crates/ai_onboarding/src/ai_upsell_card.rs       |  7 +----
crates/ai_onboarding/src/young_account_banner.rs | 19 ++---------------
crates/feature_flags/src/flags.rs                | 10 ---------
crates/language_models/Cargo.toml                |  1 
crates/language_models/src/provider/cloud.rs     | 11 +--------
8 files changed, 11 insertions(+), 49 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -486,7 +486,6 @@ dependencies = [
  "client",
  "cloud_llm_client",
  "component",
- "feature_flags",
  "gpui",
  "language_model",
  "serde",
@@ -8681,7 +8680,6 @@ dependencies = [
  "credentials_provider",
  "deepseek",
  "editor",
- "feature_flags",
  "fs",
  "futures 0.3.31",
  "google_ai",

crates/ai_onboarding/Cargo.toml 🔗

@@ -18,7 +18,6 @@ default = []
 client.workspace = true
 cloud_llm_client.workspace = true
 component.workspace = true
-feature_flags.workspace = true
 gpui.workspace = true
 language_model.workspace = true
 serde.workspace = true

crates/ai_onboarding/src/ai_onboarding.rs 🔗

@@ -18,7 +18,6 @@ pub use young_account_banner::YoungAccountBanner;
 use std::sync::Arc;
 
 use client::{Client, UserStore, zed_urls};
-use feature_flags::{BillingV2FeatureFlag, FeatureFlagAppExt as _};
 use gpui::{AnyElement, Entity, IntoElement, ParentElement};
 use ui::{Divider, RegisterComponent, Tooltip, prelude::*};
 
@@ -85,7 +84,7 @@ impl ZedAiOnboarding {
         self
     }
 
-    fn render_sign_in_disclaimer(&self, cx: &mut App) -> AnyElement {
+    fn render_sign_in_disclaimer(&self, _cx: &mut App) -> AnyElement {
         let signing_in = matches!(self.sign_in_status, SignInStatus::SigningIn);
 
         v_flex()
@@ -96,7 +95,7 @@ impl ZedAiOnboarding {
                     .color(Color::Muted)
                     .mb_2(),
             )
-            .child(PlanDefinitions.pro_plan(cx.has_flag::<BillingV2FeatureFlag>(), false))
+            .child(PlanDefinitions.pro_plan(true, false))
             .child(
                 Button::new("sign_in", "Try Zed Pro for Free")
                     .disabled(signing_in)
@@ -120,7 +119,7 @@ impl ZedAiOnboarding {
                 .max_w_full()
                 .gap_1()
                 .child(Headline::new("Welcome to Zed AI"))
-                .child(YoungAccountBanner::new(is_v2))
+                .child(YoungAccountBanner)
                 .child(
                     v_flex()
                         .mt_2()
@@ -307,7 +306,7 @@ impl RenderOnce for ZedAiOnboarding {
     fn render(self, _window: &mut ui::Window, cx: &mut App) -> impl IntoElement {
         if matches!(self.sign_in_status, SignInStatus::SignedIn) {
             match self.plan {
-                None => self.render_free_plan_state(cx.has_flag::<BillingV2FeatureFlag>(), cx),
+                None => self.render_free_plan_state(true, cx),
                 Some(plan @ (Plan::V1(PlanV1::ZedFree) | Plan::V2(PlanV2::ZedFree))) => {
                     self.render_free_plan_state(plan.is_v2(), cx)
                 }

crates/ai_onboarding/src/ai_upsell_card.rs 🔗

@@ -2,7 +2,6 @@ use std::sync::Arc;
 
 use client::{Client, UserStore, zed_urls};
 use cloud_llm_client::{Plan, PlanV1, PlanV2};
-use feature_flags::{BillingV2FeatureFlag, FeatureFlagAppExt};
 use gpui::{AnyElement, App, Entity, IntoElement, RenderOnce, Window};
 use ui::{CommonAnimationExt, Divider, Vector, VectorName, prelude::*};
 
@@ -50,9 +49,7 @@ impl AiUpsellCard {
 
 impl RenderOnce for AiUpsellCard {
     fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
-        let is_v2_plan = self
-            .user_plan
-            .map_or(cx.has_flag::<BillingV2FeatureFlag>(), |plan| plan.is_v2());
+        let is_v2_plan = self.user_plan.map_or(true, |plan| plan.is_v2());
 
         let pro_section = v_flex()
             .flex_grow()
@@ -175,7 +172,7 @@ impl RenderOnce for AiUpsellCard {
                     .child(Label::new("Try Zed AI").size(LabelSize::Large))
                     .map(|this| {
                         if self.account_too_young {
-                            this.child(YoungAccountBanner::new(is_v2_plan)).child(
+                            this.child(YoungAccountBanner).child(
                                 v_flex()
                                     .mt_2()
                                     .gap_1()

crates/ai_onboarding/src/young_account_banner.rs 🔗

@@ -2,30 +2,17 @@ use gpui::{IntoElement, ParentElement};
 use ui::{Banner, prelude::*};
 
 #[derive(IntoElement)]
-pub struct YoungAccountBanner {
-    is_v2: bool,
-}
-
-impl YoungAccountBanner {
-    pub fn new(is_v2: bool) -> Self {
-        Self { is_v2 }
-    }
-}
+pub struct YoungAccountBanner;
 
 impl RenderOnce for YoungAccountBanner {
     fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
-        const YOUNG_ACCOUNT_DISCLAIMER: &str = "To prevent abuse of our service, GitHub accounts created fewer than 30 days ago are not eligible for free plan usage or Pro plan free trial. You can request an exception by reaching out to billing-support@zed.dev";
-        const YOUNG_ACCOUNT_DISCLAIMER_V2: &str = "To prevent abuse of our service, GitHub accounts created fewer than 30 days ago are not eligible for the Pro trial. You can request an exception by reaching out to billing-support@zed.dev";
+        const YOUNG_ACCOUNT_DISCLAIMER: &str = "To prevent abuse of our service, GitHub accounts created fewer than 30 days ago are not eligible for the Pro trial. You can request an exception by reaching out to billing-support@zed.dev";
 
         let label = div()
             .w_full()
             .text_sm()
             .text_color(cx.theme().colors().text_muted)
-            .child(if self.is_v2 {
-                YOUNG_ACCOUNT_DISCLAIMER_V2
-            } else {
-                YOUNG_ACCOUNT_DISCLAIMER
-            });
+            .child(YOUNG_ACCOUNT_DISCLAIMER);
 
         div()
             .max_w_full()

crates/feature_flags/src/flags.rs 🔗

@@ -6,16 +6,6 @@ impl FeatureFlag for PredictEditsRateCompletionsFeatureFlag {
     const NAME: &'static str = "predict-edits-rate-completions";
 }
 
-pub struct BillingV2FeatureFlag {}
-
-impl FeatureFlag for BillingV2FeatureFlag {
-    const NAME: &'static str = "billing-v2";
-
-    fn enabled_for_all() -> bool {
-        true
-    }
-}
-
 pub struct NotebookFeatureFlag;
 
 impl FeatureFlag for NotebookFeatureFlag {

crates/language_models/Cargo.toml 🔗

@@ -29,7 +29,6 @@ copilot.workspace = true
 credentials_provider.workspace = true
 deepseek = { workspace = true, features = ["schemars"] }
 editor.workspace = true
-feature_flags.workspace = true
 fs.workspace = true
 futures.workspace = true
 google_ai = { workspace = true, features = ["schemars"] }

crates/language_models/src/provider/cloud.rs 🔗

@@ -11,7 +11,6 @@ use cloud_llm_client::{
     SUBSCRIPTION_LIMIT_RESOURCE_HEADER_NAME, TOOL_USE_LIMIT_REACHED_HEADER_NAME,
     ZED_VERSION_HEADER_NAME,
 };
-use feature_flags::{BillingV2FeatureFlag, FeatureFlagAppExt};
 use futures::{
     AsyncBufReadExt, FutureExt, Stream, StreamExt, future::BoxFuture, stream::BoxStream,
 };
@@ -974,13 +973,10 @@ struct ZedAiConfiguration {
 }
 
 impl RenderOnce for ZedAiConfiguration {
-    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
+    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
         let is_pro = self.plan.is_some_and(|plan| {
             matches!(plan, Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro))
         });
-        let is_free_v2 = self
-            .plan
-            .is_some_and(|plan| plan == Plan::V2(PlanV2::ZedFree));
         let subscription_text = match (self.plan, self.subscription_period) {
             (Some(Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro)), Some(_)) => {
                 "You have access to Zed's hosted models through your Pro subscription."
@@ -1047,10 +1043,7 @@ impl RenderOnce for ZedAiConfiguration {
 
         v_flex().gap_2().w_full().map(|this| {
             if self.account_too_young {
-                this.child(YoungAccountBanner::new(
-                    is_free_v2 || cx.has_flag::<BillingV2FeatureFlag>(),
-                ))
-                .child(
+                this.child(YoungAccountBanner).child(
                     Button::new("upgrade", "Upgrade to Pro")
                         .style(ui::ButtonStyle::Tinted(ui::TintColor::Accent))
                         .full_width()