Make plans backwards compatible (#37941)

This PR fixes the backwards compatibility of the new `Plan` variants.

We can't add new variants to the wire representation, as old clients
won't be able to understand them.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers
2025-09-10 20:11:07 +00:00
committed by GitHub
parent 2c29eac29f
commit cb75c2aeb7
18 changed files with 215 additions and 135 deletions
+9 -7
View File
@@ -14,6 +14,7 @@ use arrayvec::ArrayVec;
use audio::{Audio, Sound};
use buffer_diff::BufferDiff;
use client::zed_urls;
use cloud_llm_client::PlanV1;
use collections::{HashMap, HashSet};
use editor::scroll::Autoscroll;
use editor::{Editor, EditorEvent, EditorMode, MultiBuffer, PathKey, SelectionEffects};
@@ -4875,7 +4876,9 @@ impl AcpThreadView {
return None;
}
let plan = user_store.plan().unwrap_or(cloud_llm_client::Plan::ZedFree);
let plan = user_store
.plan()
.unwrap_or(cloud_llm_client::Plan::V1(PlanV1::ZedFree));
let usage = user_store.model_request_usage()?;
@@ -5134,13 +5137,12 @@ impl AcpThreadView {
cx: &mut Context<Self>,
) -> Callout {
let error_message = match plan {
cloud_llm_client::Plan::ZedPro => "Upgrade to usage-based billing for more prompts.",
cloud_llm_client::Plan::ZedProTrial | cloud_llm_client::Plan::ZedFree => {
"Upgrade to Zed Pro for more prompts."
cloud_llm_client::Plan::V1(PlanV1::ZedPro) => {
"Upgrade to usage-based billing for more prompts."
}
cloud_llm_client::Plan::ZedProV2
| cloud_llm_client::Plan::ZedProTrialV2
| cloud_llm_client::Plan::ZedFreeV2 => "",
cloud_llm_client::Plan::V1(PlanV1::ZedProTrial)
| cloud_llm_client::Plan::V1(PlanV1::ZedFree) => "Upgrade to Zed Pro for more prompts.",
cloud_llm_client::Plan::V2(_) => "",
};
Callout::new()
+8 -4
View File
@@ -8,7 +8,7 @@ use std::{ops::Range, sync::Arc};
use agent_settings::AgentSettings;
use anyhow::Result;
use assistant_tool::{ToolSource, ToolWorkingSet};
use cloud_llm_client::Plan;
use cloud_llm_client::{Plan, PlanV1, PlanV2};
use collections::HashMap;
use context_server::ContextServerId;
use editor::{Editor, SelectionEffects, scroll::Autoscroll};
@@ -515,11 +515,15 @@ impl AgentConfiguration {
.blend(cx.theme().colors().text_accent.opacity(0.2));
let (plan_name, label_color, bg_color) = match plan {
Plan::ZedFree | Plan::ZedFreeV2 => ("Free", Color::Default, free_chip_bg),
Plan::ZedProTrial | Plan::ZedProTrialV2 => {
Plan::V1(PlanV1::ZedFree) | Plan::V2(PlanV2::ZedFree) => {
("Free", Color::Default, free_chip_bg)
}
Plan::V1(PlanV1::ZedProTrial) | Plan::V2(PlanV2::ZedProTrial) => {
("Pro Trial", Color::Accent, pro_chip_bg)
}
Plan::ZedPro | Plan::ZedProV2 => ("Pro", Color::Accent, pro_chip_bg),
Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro) => {
("Pro", Color::Accent, pro_chip_bg)
}
};
Chip::new(plan_name.to_string())
+11 -6
View File
@@ -51,7 +51,7 @@ use assistant_context::{AssistantContext, ContextEvent, ContextSummary};
use assistant_slash_command::SlashCommandWorkingSet;
use assistant_tool::ToolWorkingSet;
use client::{UserStore, zed_urls};
use cloud_llm_client::{CompletionIntent, Plan, UsageLimit};
use cloud_llm_client::{CompletionIntent, Plan, PlanV1, PlanV2, UsageLimit};
use editor::{Anchor, AnchorRangeExt as _, Editor, EditorEvent, MultiBuffer};
use feature_flags::{self, ClaudeCodeFeatureFlag, FeatureFlagAppExt, GeminiAndNativeFeatureFlag};
use fs::Fs;
@@ -2976,7 +2976,10 @@ impl AgentPanel {
let plan = self.user_store.read(cx).plan();
let has_previous_trial = self.user_store.read(cx).trial_started_at().is_some();
matches!(plan, Some(Plan::ZedFree)) && has_previous_trial
matches!(
plan,
Some(Plan::V1(PlanV1::ZedFree) | Plan::V2(PlanV2::ZedFree))
) && has_previous_trial
}
fn should_render_onboarding(&self, cx: &mut Context<Self>) -> bool {
@@ -2988,7 +2991,7 @@ impl AgentPanel {
if user_store
.plan()
.is_some_and(|plan| matches!(plan, Plan::ZedPro))
.is_some_and(|plan| matches!(plan, Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro)))
&& user_store
.subscription_period()
.and_then(|period| period.0.checked_add_days(chrono::Days::new(1)))
@@ -3527,9 +3530,11 @@ impl AgentPanel {
cx: &mut Context<Self>,
) -> AnyElement {
let error_message = match plan {
Plan::ZedPro => "Upgrade to usage-based billing for more prompts.",
Plan::ZedProTrial | Plan::ZedFree => "Upgrade to Zed Pro for more prompts.",
Plan::ZedProV2 | Plan::ZedProTrialV2 | Plan::ZedFreeV2 => "",
Plan::V1(PlanV1::ZedPro) => "Upgrade to usage-based billing for more prompts.",
Plan::V1(PlanV1::ZedProTrial) | Plan::V1(PlanV1::ZedFree) => {
"Upgrade to Zed Pro for more prompts."
}
Plan::V2(_) => "",
};
Callout::new()
+2 -2
View File
@@ -1,7 +1,7 @@
#![allow(unused, dead_code)]
use client::{ModelRequestUsage, RequestUsage};
use cloud_llm_client::{Plan, UsageLimit};
use cloud_llm_client::{Plan, PlanV1, UsageLimit};
use gpui::Global;
use std::ops::{Deref, DerefMut};
use ui::prelude::*;
@@ -75,7 +75,7 @@ impl Default for DebugAccountState {
Self {
enabled: false,
trial_expired: false,
plan: Plan::ZedFree,
plan: Plan::V1(PlanV1::ZedFree),
custom_prompt_usage: ModelRequestUsage(RequestUsage {
limit: UsageLimit::Unlimited,
amount: 0,
+4 -2
View File
@@ -17,7 +17,7 @@ use agent::{
use agent_settings::{AgentProfileId, AgentSettings, CompletionMode};
use ai_onboarding::ApiKeysWithProviders;
use buffer_diff::BufferDiff;
use cloud_llm_client::CompletionIntent;
use cloud_llm_client::{CompletionIntent, PlanV1};
use collections::{HashMap, HashSet};
use editor::actions::{MoveUp, Paste};
use editor::display_map::CreaseId;
@@ -1298,7 +1298,9 @@ impl MessageEditor {
return None;
}
let plan = user_store.plan().unwrap_or(cloud_llm_client::Plan::ZedFree);
let plan = user_store
.plan()
.unwrap_or(cloud_llm_client::Plan::V1(PlanV1::ZedFree));
let usage = user_store.model_request_usage()?;
+2 -2
View File
@@ -2,7 +2,7 @@ use std::sync::Arc;
use ai_onboarding::{AgentPanelOnboardingCard, PlanDefinitions};
use client::zed_urls;
use cloud_llm_client::Plan;
use cloud_llm_client::{Plan, PlanV1};
use gpui::{AnyElement, App, IntoElement, RenderOnce, Window};
use ui::{Divider, Tooltip, prelude::*};
@@ -112,7 +112,7 @@ impl Component for EndTrialUpsell {
Some(
v_flex()
.child(EndTrialUpsell {
plan: Plan::ZedFree,
plan: Plan::V1(PlanV1::ZedFree),
dismiss_upsell: Arc::new(|_, _| {}),
})
.into_any_element(),
@@ -1,5 +1,5 @@
use client::{ModelRequestUsage, RequestUsage, zed_urls};
use cloud_llm_client::{Plan, UsageLimit};
use cloud_llm_client::{Plan, PlanV1, PlanV2, UsageLimit};
use component::{empty_example, example_group_with_title, single_example};
use gpui::{AnyElement, App, IntoElement, RenderOnce, Window};
use ui::{Callout, prelude::*};
@@ -38,20 +38,20 @@ impl RenderOnce for UsageCallout {
let (title, message, button_text, url) = if is_limit_reached {
match self.plan {
Plan::ZedFree | Plan::ZedFreeV2 => (
Plan::V1(PlanV1::ZedFree) | Plan::V2(PlanV2::ZedFree) => (
"Out of free prompts",
"Upgrade to continue, wait for the next reset, or switch to API key."
.to_string(),
"Upgrade",
zed_urls::account_url(cx),
),
Plan::ZedProTrial | Plan::ZedProTrialV2 => (
Plan::V1(PlanV1::ZedProTrial) | Plan::V2(PlanV2::ZedProTrial) => (
"Out of trial prompts",
"Upgrade to Zed Pro to continue, or switch to API key.".to_string(),
"Upgrade",
zed_urls::account_url(cx),
),
Plan::ZedPro | Plan::ZedProV2 => (
Plan::V1(PlanV1::ZedPro) | Plan::V2(PlanV2::ZedPro) => (
"Out of included prompts",
"Enable usage-based billing to continue.".to_string(),
"Manage",
@@ -60,7 +60,7 @@ impl RenderOnce for UsageCallout {
}
} else {
match self.plan {
Plan::ZedFree => (
Plan::V1(PlanV1::ZedFree) => (
"Reaching free plan limit soon",
format!(
"{remaining} remaining - Upgrade to increase limit, or switch providers",
@@ -68,7 +68,7 @@ impl RenderOnce for UsageCallout {
"Upgrade",
zed_urls::account_url(cx),
),
Plan::ZedProTrial => (
Plan::V1(PlanV1::ZedProTrial) => (
"Reaching trial limit soon",
format!(
"{remaining} remaining - Upgrade to increase limit, or switch providers",
@@ -76,7 +76,7 @@ impl RenderOnce for UsageCallout {
"Upgrade",
zed_urls::account_url(cx),
),
_ => return div().into_any_element(),
Plan::V1(PlanV1::ZedPro) | Plan::V2(_) => return div().into_any_element(),
}
};
@@ -119,7 +119,7 @@ impl Component for UsageCallout {
single_example(
"Approaching limit (90%)",
UsageCallout::new(
Plan::ZedFree,
Plan::V1(PlanV1::ZedFree),
ModelRequestUsage(RequestUsage {
limit: UsageLimit::Limited(50),
amount: 45, // 90% of limit
@@ -130,7 +130,7 @@ impl Component for UsageCallout {
single_example(
"Limit reached (100%)",
UsageCallout::new(
Plan::ZedFree,
Plan::V1(PlanV1::ZedFree),
ModelRequestUsage(RequestUsage {
limit: UsageLimit::Limited(50),
amount: 50, // 100% of limit
@@ -147,7 +147,7 @@ impl Component for UsageCallout {
single_example(
"Approaching limit (90%)",
UsageCallout::new(
Plan::ZedProTrial,
Plan::V1(PlanV1::ZedProTrial),
ModelRequestUsage(RequestUsage {
limit: UsageLimit::Limited(150),
amount: 135, // 90% of limit
@@ -158,7 +158,7 @@ impl Component for UsageCallout {
single_example(
"Limit reached (100%)",
UsageCallout::new(
Plan::ZedProTrial,
Plan::V1(PlanV1::ZedProTrial),
ModelRequestUsage(RequestUsage {
limit: UsageLimit::Limited(150),
amount: 150, // 100% of limit
@@ -175,7 +175,7 @@ impl Component for UsageCallout {
single_example(
"Limit reached (100%)",
UsageCallout::new(
Plan::ZedPro,
Plan::V1(PlanV1::ZedPro),
ModelRequestUsage(RequestUsage {
limit: UsageLimit::Limited(500),
amount: 500, // 100% of limit