Support prolite plan type (#17419)

Addresses #17353

Problem: Codex rate-limit fetching failed when the backend returned the
new `prolite` subscription plan type.

Solution: Add `prolite` to the backend/account/auth plan mappings, keep
unknown WHAM plan values decodable, and regenerate app-server plan
schemas.
This commit is contained in:
Eric Traut
2026-04-11 13:58:16 -07:00
committed by GitHub
Unverified
parent 163ae7d3e6
commit 3b948d9dd8
17 changed files with 40 additions and 4 deletions
@@ -2010,6 +2010,7 @@
"go",
"plus",
"pro",
"prolite",
"team",
"self_serve_business_usage_based",
"business",
@@ -9924,6 +9924,7 @@
"go",
"plus",
"pro",
"prolite",
"team",
"self_serve_business_usage_based",
"business",
@@ -6720,6 +6720,7 @@
"go",
"plus",
"pro",
"prolite",
"team",
"self_serve_business_usage_based",
"business",
@@ -28,6 +28,7 @@
"go",
"plus",
"pro",
"prolite",
"team",
"self_serve_business_usage_based",
"business",
@@ -33,6 +33,7 @@
"go",
"plus",
"pro",
"prolite",
"team",
"self_serve_business_usage_based",
"business",
@@ -28,6 +28,7 @@
"go",
"plus",
"pro",
"prolite",
"team",
"self_serve_business_usage_based",
"business",
@@ -51,6 +51,7 @@
"go",
"plus",
"pro",
"prolite",
"team",
"self_serve_business_usage_based",
"business",
@@ -2,4 +2,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type PlanType = "free" | "go" | "plus" | "pro" | "team" | "self_serve_business_usage_based" | "business" | "enterprise_cbp_usage_based" | "enterprise" | "edu" | "unknown";
export type PlanType = "free" | "go" | "plus" | "pro" | "prolite" | "team" | "self_serve_business_usage_based" | "business" | "enterprise_cbp_usage_based" | "enterprise" | "edu" | "unknown";
+3 -1
View File
@@ -473,6 +473,7 @@ impl Client {
crate::types::PlanType::Go => AccountPlanType::Go,
crate::types::PlanType::Plus => AccountPlanType::Plus,
crate::types::PlanType::Pro => AccountPlanType::Pro,
crate::types::PlanType::ProLite => AccountPlanType::ProLite,
crate::types::PlanType::Team => AccountPlanType::Team,
crate::types::PlanType::SelfServeBusinessUsageBased => {
AccountPlanType::SelfServeBusinessUsageBased
@@ -486,7 +487,8 @@ impl Client {
crate::types::PlanType::Guest
| crate::types::PlanType::FreeWorkspace
| crate::types::PlanType::Quorum
| crate::types::PlanType::K12 => AccountPlanType::Unknown,
| crate::types::PlanType::K12
| crate::types::PlanType::Unknown => AccountPlanType::Unknown,
}
}
@@ -65,6 +65,8 @@ pub enum PlanType {
Plus,
#[serde(rename = "pro")]
Pro,
#[serde(rename = "prolite")]
ProLite,
#[serde(rename = "free_workspace")]
FreeWorkspace,
#[serde(rename = "team")]
@@ -85,4 +87,6 @@ pub enum PlanType {
Enterprise,
#[serde(rename = "edu")]
Edu,
#[serde(rename = "unknown", other)]
Unknown,
}
+1
View File
@@ -314,6 +314,7 @@ impl CodexAuth {
InternalKnownPlan::Go => AccountPlanType::Go,
InternalKnownPlan::Plus => AccountPlanType::Plus,
InternalKnownPlan::Pro => AccountPlanType::Pro,
InternalKnownPlan::ProLite => AccountPlanType::ProLite,
InternalKnownPlan::Team => AccountPlanType::Team,
InternalKnownPlan::SelfServeBusinessUsageBased => {
AccountPlanType::SelfServeBusinessUsageBased
+6
View File
@@ -153,4 +153,10 @@ fn workspace_account_detection_matches_workspace_plans() {
..IdTokenInfo::default()
};
assert_eq!(personal.is_workspace_account(), false);
let personal = IdTokenInfo {
chatgpt_plan_type: Some(PlanType::Known(KnownPlan::ProLite)),
..IdTokenInfo::default()
};
assert_eq!(personal.is_workspace_account(), false);
}
+9
View File
@@ -12,6 +12,7 @@ pub enum PlanType {
Go,
Plus,
Pro,
ProLite,
Team,
#[serde(rename = "self_serve_business_usage_based")]
#[ts(rename = "self_serve_business_usage_based")]
@@ -53,11 +54,19 @@ mod tests {
.expect("enterprise cbp usage based should serialize"),
"\"enterprise_cbp_usage_based\""
);
assert_eq!(
serde_json::to_string(&PlanType::ProLite).expect("prolite should serialize"),
"\"prolite\""
);
assert_eq!(
serde_json::from_str::<PlanType>("\"self_serve_business_usage_based\"")
.expect("self-serve business usage based should deserialize"),
PlanType::SelfServeBusinessUsageBased
);
assert_eq!(
serde_json::from_str::<PlanType>("\"prolite\"").expect("prolite should deserialize"),
PlanType::ProLite
);
assert_eq!(
serde_json::from_str::<PlanType>("\"enterprise_cbp_usage_based\"")
.expect("enterprise cbp usage based should deserialize"),
+4
View File
@@ -16,6 +16,7 @@ impl PlanType {
"go" => Self::Known(KnownPlan::Go),
"plus" => Self::Known(KnownPlan::Plus),
"pro" => Self::Known(KnownPlan::Pro),
"prolite" => Self::Known(KnownPlan::ProLite),
"team" => Self::Known(KnownPlan::Team),
"self_serve_business_usage_based" => {
Self::Known(KnownPlan::SelfServeBusinessUsageBased)
@@ -36,6 +37,7 @@ pub enum KnownPlan {
Go,
Plus,
Pro,
ProLite,
Team,
#[serde(rename = "self_serve_business_usage_based")]
SelfServeBusinessUsageBased,
@@ -54,6 +56,7 @@ impl KnownPlan {
Self::Go => "Go",
Self::Plus => "Plus",
Self::Pro => "Pro",
Self::ProLite => "Pro Lite",
Self::Team => "Team",
Self::SelfServeBusinessUsageBased => "Self Serve Business Usage Based",
Self::Business => "Business",
@@ -69,6 +72,7 @@ impl KnownPlan {
Self::Go => "go",
Self::Plus => "plus",
Self::Pro => "pro",
Self::ProLite => "prolite",
Self::Team => "team",
Self::SelfServeBusinessUsageBased => "self_serve_business_usage_based",
Self::Business => "business",
+1 -1
View File
@@ -493,7 +493,7 @@ impl std::fmt::Display for UsageLimitReachedError {
retry_suffix_after_or(self.resets_at.as_ref())
)
}
Some(PlanType::Known(KnownPlan::Pro)) => format!(
Some(PlanType::Known(KnownPlan::Pro | KnownPlan::ProLite)) => format!(
"You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits{}",
retry_suffix_after_or(self.resets_at.as_ref())
),
+3
View File
@@ -100,6 +100,8 @@ pub(crate) fn plan_type_display_name(plan_type: PlanType) -> String {
"Business".to_string()
} else if plan_type.is_business_like() {
"Enterprise".to_string()
} else if plan_type == PlanType::ProLite {
"Pro Lite".to_string()
} else {
title_case(format!("{plan_type:?}").as_str())
}
@@ -216,6 +218,7 @@ mod tests {
(PlanType::Go, "Go"),
(PlanType::Plus, "Plus"),
(PlanType::Pro, "Pro"),
(PlanType::ProLite, "Pro Lite"),
(PlanType::Team, "Business"),
(PlanType::SelfServeBusinessUsageBased, "Business"),
(PlanType::Business, "Enterprise"),
+1 -1
View File
@@ -61,7 +61,7 @@ pub(crate) fn get_tooltip(plan: Option<PlanType>, fast_mode_enabled: bool) -> Op
Some(plan_type)
if matches!(
plan_type,
PlanType::Plus | PlanType::Enterprise | PlanType::Pro
PlanType::Plus | PlanType::Enterprise | PlanType::Pro | PlanType::ProLite
) || plan_type.is_team_like()
|| plan_type.is_business_like() =>
{