mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
Remap displayed ChatGPT plan labels
This commit is contained in:
@@ -94,14 +94,21 @@ pub(crate) fn compose_account_display(
|
||||
CoreAuthMode::ApiKey => Some(StatusAccountDisplay::ApiKey),
|
||||
CoreAuthMode::Chatgpt | CoreAuthMode::ChatgptAuthTokens => {
|
||||
let email = auth.get_account_email();
|
||||
let plan = plan
|
||||
.map(|plan_type| title_case(format!("{plan_type:?}").as_str()))
|
||||
.or_else(|| Some("Unknown".to_string()));
|
||||
let plan = plan.map(plan_type_display_name);
|
||||
let plan = plan.or_else(|| Some("Unknown".to_string()));
|
||||
Some(StatusAccountDisplay::ChatGpt { email, plan })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn plan_type_display_name(plan_type: PlanType) -> String {
|
||||
match plan_type {
|
||||
PlanType::Team => "Business".to_string(),
|
||||
PlanType::Business => "Enterprise".to_string(),
|
||||
_ => title_case(format!("{plan_type:?}").as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn format_tokens_compact(value: i64) -> String {
|
||||
let value = value.max(0);
|
||||
if value == 0 {
|
||||
@@ -187,3 +194,44 @@ pub(crate) fn title_case(s: &str) -> String {
|
||||
let rest: String = chars.as_str().to_ascii_lowercase();
|
||||
first.to_uppercase().collect::<String>() + &rest
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codex_core::auth::CodexAuth;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn plan_type_display_name_remaps_display_labels() {
|
||||
let cases = [
|
||||
(PlanType::Free, "Free"),
|
||||
(PlanType::Go, "Go"),
|
||||
(PlanType::Plus, "Plus"),
|
||||
(PlanType::Pro, "Pro"),
|
||||
(PlanType::Team, "Business"),
|
||||
(PlanType::Business, "Enterprise"),
|
||||
(PlanType::Enterprise, "Enterprise"),
|
||||
(PlanType::Edu, "Edu"),
|
||||
(PlanType::Unknown, "Unknown"),
|
||||
];
|
||||
|
||||
for (plan_type, expected) in cases {
|
||||
assert_eq!(plan_type_display_name(plan_type), expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compose_account_display_uses_remapped_plan_label() {
|
||||
let auth_manager =
|
||||
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
|
||||
|
||||
let display = compose_account_display(auth_manager.as_ref(), Some(PlanType::Team));
|
||||
assert!(matches!(
|
||||
display,
|
||||
Some(StatusAccountDisplay::ChatGpt {
|
||||
email: None,
|
||||
plan: Some(ref plan),
|
||||
}) if plan == "Business"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::bottom_pane::FeedbackAudience;
|
||||
use crate::status::StatusAccountDisplay;
|
||||
use crate::status::plan_type_display_name;
|
||||
use codex_app_server_client::AppServerClient;
|
||||
use codex_app_server_client::AppServerEvent;
|
||||
use codex_app_server_client::AppServerRequestHandle;
|
||||
@@ -228,7 +229,7 @@ impl AppServerSession {
|
||||
Some(TelemetryAuthMode::Chatgpt),
|
||||
Some(StatusAccountDisplay::ChatGpt {
|
||||
email: Some(email),
|
||||
plan: Some(title_case(format!("{plan_type:?}").as_str())),
|
||||
plan: Some(plan_type_display_name(plan_type)),
|
||||
}),
|
||||
Some(plan_type),
|
||||
feedback_audience,
|
||||
@@ -733,19 +734,6 @@ impl AppServerSession {
|
||||
}
|
||||
}
|
||||
|
||||
fn title_case(s: &str) -> String {
|
||||
if s.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
|
||||
let mut chars = s.chars();
|
||||
let Some(first) = chars.next() else {
|
||||
return String::new();
|
||||
};
|
||||
let rest = chars.as_str().to_ascii_lowercase();
|
||||
first.to_uppercase().collect::<String>() + &rest
|
||||
}
|
||||
|
||||
pub(crate) fn status_account_display_from_auth_mode(
|
||||
auth_mode: Option<AuthMode>,
|
||||
plan_type: Option<codex_protocol::account::PlanType>,
|
||||
@@ -755,7 +743,7 @@ pub(crate) fn status_account_display_from_auth_mode(
|
||||
Some(AuthMode::Chatgpt) | Some(AuthMode::ChatgptAuthTokens) => {
|
||||
Some(StatusAccountDisplay::ChatGpt {
|
||||
email: None,
|
||||
plan: plan_type.map(|plan_type| title_case(format!("{plan_type:?}").as_str())),
|
||||
plan: plan_type.map(plan_type_display_name),
|
||||
})
|
||||
}
|
||||
None => None,
|
||||
@@ -1264,4 +1252,31 @@ mod tests {
|
||||
assert_ne!(session.history_log_id, 0);
|
||||
assert_eq!(session.history_entry_count, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn status_account_display_from_auth_mode_uses_remapped_plan_labels() {
|
||||
let business = status_account_display_from_auth_mode(
|
||||
Some(AuthMode::Chatgpt),
|
||||
Some(codex_protocol::account::PlanType::Business),
|
||||
);
|
||||
assert!(matches!(
|
||||
business,
|
||||
Some(StatusAccountDisplay::ChatGpt {
|
||||
email: None,
|
||||
plan: Some(ref plan),
|
||||
}) if plan == "Enterprise"
|
||||
));
|
||||
|
||||
let team = status_account_display_from_auth_mode(
|
||||
Some(AuthMode::Chatgpt),
|
||||
Some(codex_protocol::account::PlanType::Team),
|
||||
);
|
||||
assert!(matches!(
|
||||
team,
|
||||
Some(StatusAccountDisplay::ChatGpt {
|
||||
email: None,
|
||||
plan: Some(ref plan),
|
||||
}) if plan == "Business"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use chrono::DateTime;
|
||||
use chrono::Local;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::project_doc::discover_project_doc_paths;
|
||||
use codex_protocol::account::PlanType;
|
||||
use std::path::Path;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
@@ -86,6 +87,14 @@ pub(crate) fn compose_account_display(
|
||||
account_display.cloned()
|
||||
}
|
||||
|
||||
pub(crate) fn plan_type_display_name(plan_type: PlanType) -> String {
|
||||
match plan_type {
|
||||
PlanType::Team => "Business".to_string(),
|
||||
PlanType::Business => "Enterprise".to_string(),
|
||||
_ => title_case(format!("{plan_type:?}").as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn format_tokens_compact(value: i64) -> String {
|
||||
let value = value.max(0);
|
||||
if value == 0 {
|
||||
@@ -158,3 +167,40 @@ pub(crate) fn format_reset_timestamp(dt: DateTime<Local>, captured_at: DateTime<
|
||||
format!("{time} on {}", dt.format("%-d %b"))
|
||||
}
|
||||
}
|
||||
|
||||
fn title_case(s: &str) -> String {
|
||||
if s.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
let mut chars = s.chars();
|
||||
let Some(first) = chars.next() else {
|
||||
return String::new();
|
||||
};
|
||||
let rest = chars.as_str().to_ascii_lowercase();
|
||||
first.to_uppercase().collect::<String>() + &rest
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn plan_type_display_name_remaps_display_labels() {
|
||||
let cases = [
|
||||
(PlanType::Free, "Free"),
|
||||
(PlanType::Go, "Go"),
|
||||
(PlanType::Plus, "Plus"),
|
||||
(PlanType::Pro, "Pro"),
|
||||
(PlanType::Team, "Business"),
|
||||
(PlanType::Business, "Enterprise"),
|
||||
(PlanType::Enterprise, "Enterprise"),
|
||||
(PlanType::Edu, "Edu"),
|
||||
(PlanType::Unknown, "Unknown"),
|
||||
];
|
||||
|
||||
for (plan_type, expected) in cases {
|
||||
assert_eq!(plan_type_display_name(plan_type), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ pub(crate) use card::new_status_output;
|
||||
pub(crate) use card::new_status_output_with_rate_limits;
|
||||
pub(crate) use helpers::format_directory_display;
|
||||
pub(crate) use helpers::format_tokens_compact;
|
||||
pub(crate) use helpers::plan_type_display_name;
|
||||
pub(crate) use rate_limits::RateLimitSnapshotDisplay;
|
||||
pub(crate) use rate_limits::RateLimitWindowDisplay;
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user