cloud_llm_client: Move Plan type into cloud_api_types (#47778)

This PR moves the `Plan` type out of `cloud_llm_client` and into
`cloud_api_types`.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2026-01-27 10:58:05 -05:00 committed by GitHub
parent 73bb119126
commit 4723dbe696
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 87 additions and 71 deletions

7
Cargo.lock generated
View file

@ -164,6 +164,7 @@ dependencies = [
"chrono",
"client",
"clock",
"cloud_api_types",
"cloud_llm_client",
"collections",
"context_server",
@ -351,6 +352,7 @@ dependencies = [
"chrono",
"client",
"clock",
"cloud_api_types",
"cloud_llm_client",
"collections",
"command_palette_hooks",
@ -497,7 +499,7 @@ name = "ai_onboarding"
version = "0.1.0"
dependencies = [
"client",
"cloud_llm_client",
"cloud_api_types",
"component",
"gpui",
"language_model",
@ -9069,6 +9071,7 @@ dependencies = [
"bedrock",
"chrono",
"client",
"cloud_api_types",
"cloud_llm_client",
"collections",
"component",
@ -17100,7 +17103,7 @@ dependencies = [
"channel",
"chrono",
"client",
"cloud_llm_client",
"cloud_api_types",
"collections",
"db",
"git_ui",

View file

@ -26,6 +26,7 @@ agent_settings.workspace = true
anyhow.workspace = true
chrono.workspace = true
client.workspace = true
cloud_api_types.workspace = true
cloud_llm_client.workspace = true
collections.workspace = true
context_server.workspace = true

View file

@ -18,7 +18,8 @@ use agent_settings::{
use anyhow::{Context as _, Result, anyhow};
use chrono::{DateTime, Utc};
use client::UserStore;
use cloud_llm_client::{CompletionIntent, Plan};
use cloud_api_types::Plan;
use cloud_llm_client::CompletionIntent;
use collections::{HashMap, HashSet, IndexMap};
use fs::Fs;
use futures::stream;

View file

@ -43,6 +43,7 @@ audio.workspace = true
buffer_diff.workspace = true
chrono.workspace = true
client.workspace = true
cloud_api_types.workspace = true
cloud_llm_client.workspace = true
collections.workspace = true
command_palette_hooks.workspace = true

View file

@ -9,7 +9,7 @@ use std::{ops::Range, sync::Arc};
use agent::ContextServerRegistry;
use anyhow::Result;
use client::zed_urls;
use cloud_llm_client::{Plan, PlanV2};
use cloud_api_types::{Plan, PlanV2};
use collections::HashMap;
use context_server::ContextServerId;
use editor::{Editor, MultiBufferOffset, SelectionEffects, scroll::Autoscroll};

View file

@ -37,7 +37,7 @@ use anyhow::{Result, anyhow};
use assistant_slash_command::SlashCommandWorkingSet;
use assistant_text_thread::{TextThread, TextThreadEvent, TextThreadSummary};
use client::UserStore;
use cloud_llm_client::{Plan, PlanV2};
use cloud_api_types::{Plan, PlanV2};
use editor::{Anchor, AnchorRangeExt as _, Editor, EditorEvent, MultiBuffer};
use extension::ExtensionEvents;
use extension_host::ExtensionStore;

View file

@ -16,7 +16,7 @@ default = []
[dependencies]
client.workspace = true
cloud_llm_client.workspace = true
cloud_api_types.workspace = true
component.workspace = true
gpui.workspace = true
language_model.workspace = true

View file

@ -1,7 +1,7 @@
use std::sync::Arc;
use client::{Client, UserStore};
use cloud_llm_client::{Plan, PlanV2};
use cloud_api_types::{Plan, PlanV2};
use gpui::{Entity, IntoElement, ParentElement};
use language_model::{LanguageModelRegistry, ZED_CLOUD_PROVIDER_ID};
use ui::prelude::*;

View file

@ -10,7 +10,7 @@ pub use agent_api_keys_onboarding::{ApiKeysWithProviders, ApiKeysWithoutProvider
pub use agent_panel_onboarding_card::AgentPanelOnboardingCard;
pub use agent_panel_onboarding_content::AgentPanelOnboarding;
pub use ai_upsell_card::AiUpsellCard;
use cloud_llm_client::{Plan, PlanV2};
use cloud_api_types::{Plan, PlanV2};
pub use edit_prediction_onboarding_content::EditPredictionOnboarding;
pub use plan_definitions::PlanDefinitions;
pub use young_account_banner::YoungAccountBanner;

View file

@ -1,7 +1,7 @@
use std::sync::Arc;
use client::{Client, UserStore, zed_urls};
use cloud_llm_client::{Plan, PlanV2};
use cloud_api_types::{Plan, PlanV2};
use gpui::{AnyElement, App, Entity, IntoElement, RenderOnce, Window};
use ui::{CommonAnimationExt, Divider, Vector, VectorName, prelude::*};

View file

@ -1,7 +1,7 @@
use std::sync::Arc;
use client::{Client, UserStore};
use cloud_llm_client::{Plan, PlanV2};
use cloud_api_types::{Plan, PlanV2};
use gpui::{Entity, IntoElement, ParentElement};
use ui::prelude::*;

View file

@ -1,7 +1,7 @@
use crate::{Client, Connection, Credentials, EstablishConnectionError, UserStore};
use anyhow::{Context as _, Result, anyhow};
use cloud_api_client::{AuthenticatedUser, GetAuthenticatedUserResponse, PlanInfo};
use cloud_llm_client::{CurrentUsage, PlanV2, UsageData, UsageLimit};
use cloud_api_client::{AuthenticatedUser, GetAuthenticatedUserResponse, PlanInfo, PlanV2};
use cloud_llm_client::{CurrentUsage, UsageData, UsageLimit};
use futures::{StreamExt, stream::BoxStream};
use gpui::{AppContext as _, Entity, TestAppContext};
use http_client::{AsyncBody, Method, Request, http};

View file

@ -2,10 +2,9 @@ use super::{Client, Status, TypedEnvelope, proto};
use anyhow::{Context as _, Result};
use chrono::{DateTime, Utc};
use cloud_api_client::websocket_protocol::MessageToClient;
use cloud_api_client::{GetAuthenticatedUserResponse, PlanInfo};
use cloud_api_client::{GetAuthenticatedUserResponse, Plan, PlanInfo};
use cloud_llm_client::{
EDIT_PREDICTIONS_USAGE_AMOUNT_HEADER_NAME, EDIT_PREDICTIONS_USAGE_LIMIT_HEADER_NAME, Plan,
UsageLimit,
EDIT_PREDICTIONS_USAGE_AMOUNT_HEADER_NAME, EDIT_PREDICTIONS_USAGE_LIMIT_HEADER_NAME, UsageLimit,
};
use collections::{HashMap, HashSet, hash_map::Entry};
use derive_more::Deref;
@ -669,7 +668,7 @@ impl UserStore {
pub fn plan(&self) -> Option<Plan> {
#[cfg(debug_assertions)]
if let Ok(plan) = std::env::var("ZED_SIMULATE_PLAN").as_ref() {
use cloud_llm_client::PlanV2;
use cloud_api_client::PlanV2;
return match plan.as_str() {
"free" => Some(Plan::V2(PlanV2::ZedFree)),

View file

@ -1,9 +1,10 @@
mod plan;
mod timestamp;
pub mod websocket_protocol;
use cloud_llm_client::Plan;
use serde::{Deserialize, Serialize};
pub use crate::plan::*;
pub use crate::timestamp::Timestamp;
pub const ZED_SYSTEM_ID_HEADER_NAME: &str = "x-zed-system-id";
@ -26,28 +27,6 @@ pub struct AuthenticatedUser {
pub accepted_tos_at: Option<Timestamp>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct PlanInfo {
pub plan_v2: cloud_llm_client::PlanV2,
pub subscription_period: Option<SubscriptionPeriod>,
pub usage: cloud_llm_client::CurrentUsage,
pub trial_started_at: Option<Timestamp>,
pub is_account_too_young: bool,
pub has_overdue_invoices: bool,
}
impl PlanInfo {
pub fn plan(&self) -> Plan {
Plan::V2(self.plan_v2)
}
}
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
pub struct SubscriptionPeriod {
pub started_at: Timestamp,
pub ended_at: Timestamp,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct AcceptTermsOfServiceResponse {
pub user: AuthenticatedUser,

View file

@ -0,0 +1,59 @@
use serde::{Deserialize, Serialize};
use crate::Timestamp;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Plan {
V2(PlanV2),
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PlanV2 {
#[default]
ZedFree,
ZedPro,
ZedProTrial,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct PlanInfo {
pub plan_v2: PlanV2,
pub subscription_period: Option<SubscriptionPeriod>,
pub usage: cloud_llm_client::CurrentUsage,
pub trial_started_at: Option<Timestamp>,
pub is_account_too_young: bool,
pub has_overdue_invoices: bool,
}
impl PlanInfo {
pub fn plan(&self) -> Plan {
Plan::V2(self.plan_v2)
}
}
#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]
pub struct SubscriptionPeriod {
pub started_at: Timestamp,
pub ended_at: Timestamp,
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use serde_json::json;
use super::*;
#[test]
fn test_plan_v2_deserialize_snake_case() {
let plan = serde_json::from_value::<PlanV2>(json!("zed_free")).unwrap();
assert_eq!(plan, PlanV2::ZedFree);
let plan = serde_json::from_value::<PlanV2>(json!("zed_pro")).unwrap();
assert_eq!(plan, PlanV2::ZedPro);
let plan = serde_json::from_value::<PlanV2>(json!("zed_pro_trial")).unwrap();
assert_eq!(plan, PlanV2::ZedProTrial);
}
}

View file

@ -74,20 +74,6 @@ impl FromStr for UsageLimit {
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Plan {
V2(PlanV2),
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PlanV2 {
#[default]
ZedFree,
ZedPro,
ZedProTrial,
}
#[derive(
Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize, Deserialize, EnumString, EnumIter, Display,
)]
@ -337,23 +323,8 @@ pub struct UsageData {
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use serde_json::json;
use super::*;
#[test]
fn test_plan_v2_deserialize_snake_case() {
let plan = serde_json::from_value::<PlanV2>(json!("zed_free")).unwrap();
assert_eq!(plan, PlanV2::ZedFree);
let plan = serde_json::from_value::<PlanV2>(json!("zed_pro")).unwrap();
assert_eq!(plan, PlanV2::ZedPro);
let plan = serde_json::from_value::<PlanV2>(json!("zed_pro_trial")).unwrap();
assert_eq!(plan, PlanV2::ZedProTrial);
}
#[test]
fn test_usage_limit_from_str() {
let limit = UsageLimit::from_str("unlimited").unwrap();

View file

@ -21,6 +21,7 @@ aws_http_client.workspace = true
bedrock.workspace = true
chrono.workspace = true
client.workspace = true
cloud_api_types.workspace = true
cloud_llm_client.workspace = true
collections.workspace = true
component.workspace = true

View file

@ -3,9 +3,10 @@ use anthropic::AnthropicModelMode;
use anyhow::{Context as _, Result, anyhow};
use chrono::{DateTime, Utc};
use client::{Client, UserStore, zed_urls};
use cloud_api_types::{Plan, PlanV2};
use cloud_llm_client::{
CLIENT_SUPPORTS_STATUS_MESSAGES_HEADER_NAME, CLIENT_SUPPORTS_X_AI_HEADER_NAME, CompletionBody,
CompletionEvent, CountTokensBody, CountTokensResponse, ListModelsResponse, Plan, PlanV2,
CompletionEvent, CountTokensBody, CountTokensResponse, ListModelsResponse,
SERVER_SUPPORTS_STATUS_MESSAGES_HEADER_NAME, ZED_VERSION_HEADER_NAME,
};
use feature_flags::{CloudThinkingToggleFeatureFlag, FeatureFlagAppExt as _};

View file

@ -36,7 +36,7 @@ call.workspace = true
channel.workspace = true
chrono.workspace = true
client.workspace = true
cloud_llm_client.workspace = true
cloud_api_types.workspace = true
db.workspace = true
git_ui.workspace = true
gpui = { workspace = true, features = ["screen-capture"] }

View file

@ -21,7 +21,7 @@ use crate::application_menu::{
use auto_update::AutoUpdateStatus;
use call::ActiveCall;
use client::{Client, UserStore, zed_urls};
use cloud_llm_client::{Plan, PlanV2};
use cloud_api_types::{Plan, PlanV2};
use gpui::{
Action, AnyElement, App, Context, Corner, Element, Entity, FocusHandle, Focusable,
InteractiveElement, IntoElement, MouseButton, ParentElement, Render,