fix(auth): isolate chatgptAuthTokens concept to auth manager and app-server (#10423)

So that the rest of the codebase (like TUI) don't need to be concerned
whether ChatGPT auth was handled by Codex itself or passed in via
app-server's external auth mode.
This commit is contained in:
Owen Lin
2026-02-05 10:46:06 -08:00
committed by GitHub
Unverified
parent 5c0fd62ff1
commit 3582b74d01
20 changed files with 92 additions and 71 deletions
-1
View File
@@ -1917,7 +1917,6 @@ version = "0.0.0"
dependencies = [
"chrono",
"codex-api",
"codex-app-server-protocol",
"codex-protocol",
"codex-utils-absolute-path",
"codex-utils-string",
@@ -152,6 +152,7 @@ use codex_core::SessionMeta;
use codex_core::ThreadConfigSnapshot;
use codex_core::ThreadManager;
use codex_core::ThreadSortKey as CoreThreadSortKey;
use codex_core::auth::AuthMode as CoreAuthMode;
use codex_core::auth::CLIENT_ID;
use codex_core::auth::login_with_api_key;
use codex_core::auth::login_with_chatgpt_auth_tokens;
@@ -1188,7 +1189,7 @@ impl CodexMessageProcessor {
.await;
let payload_v2 = AccountUpdatedNotification {
auth_mode: self.auth_manager.get_auth_mode(),
auth_mode: self.auth_manager.get_api_auth_mode(),
};
self.outgoing
.send_server_notification(ServerNotification::AccountUpdated(payload_v2))
@@ -1336,14 +1337,16 @@ impl CodexMessageProcessor {
}
let account = match self.auth_manager.auth_cached() {
Some(auth) => Some(match auth {
CodexAuth::ApiKey(_) => Account::ApiKey {},
CodexAuth::Chatgpt(_) | CodexAuth::ChatgptAuthTokens(_) => {
Some(auth) => match auth.auth_mode() {
CoreAuthMode::ApiKey => Some(Account::ApiKey {}),
CoreAuthMode::Chatgpt => {
let email = auth.get_account_email();
let plan_type = auth.account_plan_type();
match (email, plan_type) {
(Some(email), Some(plan_type)) => Account::Chatgpt { email, plan_type },
(Some(email), Some(plan_type)) => {
Some(Account::Chatgpt { email, plan_type })
}
_ => {
let error = JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
@@ -1357,7 +1360,7 @@ impl CodexMessageProcessor {
}
}
}
}),
},
None => None,
};
+2 -6
View File
@@ -1,7 +1,7 @@
use codex_app_server_protocol::AuthMode;
use codex_common::CliConfigOverrides;
use codex_core::CodexAuth;
use codex_core::auth::AuthCredentialsStoreMode;
use codex_core::auth::AuthMode;
use codex_core::auth::CLIENT_ID;
use codex_core::auth::login_with_api_key;
use codex_core::auth::logout;
@@ -225,7 +225,7 @@ pub async fn run_login_status(cli_config_overrides: CliConfigOverrides) -> ! {
let config = load_config_or_exit(cli_config_overrides).await;
match CodexAuth::from_auth_storage(&config.codex_home, config.cli_auth_credentials_store_mode) {
Ok(Some(auth)) => match auth.api_auth_mode() {
Ok(Some(auth)) => match auth.auth_mode() {
AuthMode::ApiKey => match auth.get_token() {
Ok(api_key) => {
eprintln!("Logged in using an API key - {}", safe_format_key(&api_key));
@@ -240,10 +240,6 @@ pub async fn run_login_status(cli_config_overrides: CliConfigOverrides) -> ! {
eprintln!("Logged in using ChatGPT");
std::process::exit(0);
}
AuthMode::ChatgptAuthTokens => {
eprintln!("Logged in using ChatGPT (external tokens)");
std::process::exit(0);
}
},
Ok(None) => {
eprintln!("Not logged in");
+19 -11
View File
@@ -16,6 +16,7 @@ use std::sync::Mutex;
use std::sync::RwLock;
use codex_app_server_protocol::AuthMode as ApiAuthMode;
use codex_otel::TelemetryAuthMode;
use codex_protocol::config_types::ForcedLoginMethod;
pub use crate::auth::storage::AuthCredentialsStoreMode;
@@ -47,6 +48,15 @@ pub enum AuthMode {
Chatgpt,
}
impl From<AuthMode> for TelemetryAuthMode {
fn from(mode: AuthMode) -> Self {
match mode {
AuthMode::ApiKey => TelemetryAuthMode::ApiKey,
AuthMode::Chatgpt => TelemetryAuthMode::Chatgpt,
}
}
}
/// Authentication mechanism used by the current user.
#[derive(Debug, Clone)]
pub enum CodexAuth {
@@ -186,7 +196,7 @@ impl CodexAuth {
load_auth(codex_home, false, auth_credentials_store_mode)
}
pub fn internal_auth_mode(&self) -> AuthMode {
pub fn auth_mode(&self) -> AuthMode {
match self {
Self::ApiKey(_) => AuthMode::ApiKey,
Self::Chatgpt(_) | Self::ChatgptAuthTokens(_) => AuthMode::Chatgpt,
@@ -202,14 +212,14 @@ impl CodexAuth {
}
pub fn is_chatgpt_auth(&self) -> bool {
self.internal_auth_mode() == AuthMode::Chatgpt
self.auth_mode() == AuthMode::Chatgpt
}
pub fn is_external_chatgpt_tokens(&self) -> bool {
matches!(self, Self::ChatgptAuthTokens(_))
}
/// Returns `None` is `is_internal_auth_mode() != AuthMode::ApiKey`.
/// Returns `None` if `auth_mode() != AuthMode::ApiKey`.
pub fn api_key(&self) -> Option<&str> {
match self {
Self::ApiKey(auth) => Some(auth.api_key.as_str()),
@@ -434,7 +444,7 @@ pub fn enforce_login_restrictions(config: &Config) -> std::io::Result<()> {
};
if let Some(required_method) = config.forced_login_method {
let method_violation = match (required_method, auth.internal_auth_mode()) {
let method_violation = match (required_method, auth.auth_mode()) {
(ForcedLoginMethod::Api, AuthMode::ApiKey) => None,
(ForcedLoginMethod::Chatgpt, AuthMode::Chatgpt) => None,
(ForcedLoginMethod::Api, AuthMode::Chatgpt) => Some(
@@ -1158,14 +1168,12 @@ impl AuthManager {
Ok(removed)
}
pub fn get_auth_mode(&self) -> Option<ApiAuthMode> {
pub fn get_api_auth_mode(&self) -> Option<ApiAuthMode> {
self.auth_cached().as_ref().map(CodexAuth::api_auth_mode)
}
pub fn get_internal_auth_mode(&self) -> Option<AuthMode> {
self.auth_cached()
.as_ref()
.map(CodexAuth::internal_auth_mode)
pub fn auth_mode(&self) -> Option<AuthMode> {
self.auth_cached().as_ref().map(CodexAuth::auth_mode)
}
async fn refresh_if_stale(&self, auth: &CodexAuth) -> Result<bool, RefreshTokenError> {
@@ -1373,7 +1381,7 @@ mod tests {
.unwrap()
.unwrap();
assert_eq!(None, auth.api_key());
assert_eq!(AuthMode::Chatgpt, auth.internal_auth_mode());
assert_eq!(AuthMode::Chatgpt, auth.auth_mode());
let auth_dot_json = auth
.get_current_auth_json()
@@ -1418,7 +1426,7 @@ mod tests {
let auth = super::load_auth(dir.path(), false, AuthCredentialsStoreMode::File)
.unwrap()
.unwrap();
assert_eq!(auth.internal_auth_mode(), AuthMode::ApiKey);
assert_eq!(auth.auth_mode(), AuthMode::ApiKey);
assert_eq!(auth.api_key(), Some("sk-test-key"));
assert!(auth.get_token_data().is_err());
+4 -4
View File
@@ -225,7 +225,7 @@ impl ModelClient {
let api_provider = self
.state
.provider
.to_api_provider(auth.as_ref().map(CodexAuth::internal_auth_mode))?;
.to_api_provider(auth.as_ref().map(CodexAuth::auth_mode))?;
let api_auth = auth_provider_from_auth(auth.clone(), &self.state.provider)?;
let transport = ReqwestTransport::new(build_reqwest_client());
let request_telemetry = Self::build_request_telemetry(otel_manager);
@@ -271,7 +271,7 @@ impl ModelClient {
let api_provider = self
.state
.provider
.to_api_provider(auth.as_ref().map(CodexAuth::internal_auth_mode))?;
.to_api_provider(auth.as_ref().map(CodexAuth::auth_mode))?;
let api_auth = auth_provider_from_auth(auth, &self.state.provider)?;
let transport = ReqwestTransport::new(build_reqwest_client());
let request_telemetry = Self::build_request_telemetry(otel_manager);
@@ -557,7 +557,7 @@ impl ModelClientSession {
.client
.state
.provider
.to_api_provider(auth.as_ref().map(CodexAuth::internal_auth_mode))?;
.to_api_provider(auth.as_ref().map(CodexAuth::auth_mode))?;
let api_auth = auth_provider_from_auth(auth.clone(), &self.client.state.provider)?;
let transport = ReqwestTransport::new(build_reqwest_client());
let (request_telemetry, sse_telemetry) = Self::build_streaming_telemetry(otel_manager);
@@ -622,7 +622,7 @@ impl ModelClientSession {
.client
.state
.provider
.to_api_provider(auth.as_ref().map(CodexAuth::internal_auth_mode))?;
.to_api_provider(auth.as_ref().map(CodexAuth::auth_mode))?;
let api_auth = auth_provider_from_auth(auth.clone(), &self.client.state.provider)?;
let compression = self.responses_request_compression(auth.as_ref());
+6 -4
View File
@@ -207,6 +207,7 @@ use crate::util::backoff;
use crate::windows_sandbox::WindowsSandboxLevelExt;
use codex_async_utils::OrCancelExt;
use codex_otel::OtelManager;
use codex_otel::TelemetryAuthMode;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::Personality;
use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
@@ -949,13 +950,14 @@ impl Session {
maybe_push_unstable_features_warning(&config, &mut post_session_configured_events);
let auth = auth.as_ref();
let auth_mode = auth.map(CodexAuth::auth_mode).map(TelemetryAuthMode::from);
let otel_manager = OtelManager::new(
conversation_id,
session_configuration.collaboration_mode.model(),
session_configuration.collaboration_mode.model(),
auth.and_then(CodexAuth::get_account_id),
auth.and_then(CodexAuth::get_account_email),
auth.map(CodexAuth::api_auth_mode),
auth_mode,
config.otel.log_user_prompt,
terminal::user_agent(),
session_configuration.session_source.clone(),
@@ -4518,7 +4520,7 @@ async fn try_run_sampling_request(
approval_policy = turn_context.approval_policy,
sandbox_policy = turn_context.sandbox_policy,
effort = turn_context.reasoning_effort,
auth_mode = sess.services.auth_manager.get_auth_mode(),
auth_mode = sess.services.auth_manager.auth_mode(),
features = sess.features.enabled_features(),
);
@@ -4842,7 +4844,7 @@ mod tests {
use crate::tools::registry::ToolHandler;
use crate::turn_diff_tracker::TurnDiffTracker;
use codex_app_server_protocol::AppInfo;
use codex_app_server_protocol::AuthMode;
use codex_otel::TelemetryAuthMode;
use codex_protocol::models::BaseInstructions;
use codex_protocol::models::ContentItem;
use codex_protocol::models::ResponseInputItem;
@@ -5652,7 +5654,7 @@ mod tests {
model_info.slug.as_str(),
None,
Some("test@test.com".to_string()),
Some(AuthMode::Chatgpt),
Some(TelemetryAuthMode::Chatgpt),
false,
"test".to_string(),
session_source,
+5 -8
View File
@@ -61,7 +61,7 @@ impl ModelsManager {
let cache_path = codex_home.join(MODEL_CACHE_FILE);
let cache_manager = ModelsCacheManager::new(cache_path, DEFAULT_MODEL_CACHE_TTL);
Self {
local_models: builtin_model_presets(auth_manager.get_internal_auth_mode()),
local_models: builtin_model_presets(auth_manager.auth_mode()),
remote_models: RwLock::new(Self::load_remote_models_from_file().unwrap_or_default()),
auth_manager,
etag: RwLock::new(None),
@@ -175,7 +175,7 @@ impl ModelsManager {
refresh_strategy: RefreshStrategy,
) -> CoreResult<()> {
if !config.features.enabled(Feature::RemoteModels)
|| self.auth_manager.get_internal_auth_mode() == Some(AuthMode::ApiKey)
|| self.auth_manager.auth_mode() == Some(AuthMode::ApiKey)
{
return Ok(());
}
@@ -204,7 +204,7 @@ impl ModelsManager {
let _timer =
codex_otel::start_global_timer("codex.remote_models.fetch_update.duration_ms", &[]);
let auth = self.auth_manager.auth().await;
let auth_mode = self.auth_manager.get_internal_auth_mode();
let auth_mode = self.auth_manager.auth_mode();
let api_provider = self.provider.to_api_provider(auth_mode)?;
let api_auth = auth_provider_from_auth(auth.clone(), &self.provider)?;
let transport = ReqwestTransport::new(build_reqwest_client());
@@ -275,10 +275,7 @@ impl ModelsManager {
let remote_presets: Vec<ModelPreset> = remote_models.into_iter().map(Into::into).collect();
let existing_presets = self.local_models.clone();
let mut merged_presets = ModelPreset::merge(remote_presets, existing_presets);
let chatgpt_mode = matches!(
self.auth_manager.get_internal_auth_mode(),
Some(AuthMode::Chatgpt)
);
let chatgpt_mode = matches!(self.auth_manager.auth_mode(), Some(AuthMode::Chatgpt));
merged_presets = ModelPreset::filter_by_auth(merged_presets, chatgpt_mode);
for preset in &mut merged_presets {
@@ -322,7 +319,7 @@ impl ModelsManager {
let cache_path = codex_home.join(MODEL_CACHE_FILE);
let cache_manager = ModelsCacheManager::new(cache_path, DEFAULT_MODEL_CACHE_TTL);
Self {
local_models: builtin_model_presets(auth_manager.get_internal_auth_mode()),
local_models: builtin_model_presets(auth_manager.auth_mode()),
remote_models: RwLock::new(Self::load_remote_models_from_file().unwrap_or_default()),
auth_manager,
etag: RwLock::new(None),
+6 -5
View File
@@ -1,7 +1,6 @@
use std::process::Command;
use std::sync::Arc;
use codex_app_server_protocol::AuthMode;
use codex_core::AuthManager;
use codex_core::CodexAuth;
use codex_core::ContentItem;
@@ -14,6 +13,7 @@ use codex_core::WEB_SEARCH_ELIGIBLE_HEADER;
use codex_core::WireApi;
use codex_core::models_manager::manager::ModelsManager;
use codex_otel::OtelManager;
use codex_otel::TelemetryAuthMode;
use codex_protocol::ThreadId;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::config_types::WebSearchMode;
@@ -72,7 +72,7 @@ async fn responses_stream_includes_subagent_header_on_review() {
let config = Arc::new(config);
let conversation_id = ThreadId::new();
let auth_mode = AuthMode::Chatgpt;
let auth_mode = TelemetryAuthMode::Chatgpt;
let session_source = SessionSource::SubAgent(SubAgentSource::Review);
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
let otel_manager = OtelManager::new(
@@ -182,7 +182,7 @@ async fn responses_stream_includes_subagent_header_on_other() {
let config = Arc::new(config);
let conversation_id = ThreadId::new();
let auth_mode = AuthMode::Chatgpt;
let auth_mode = TelemetryAuthMode::Chatgpt;
let session_source = SessionSource::SubAgent(SubAgentSource::Other("my-task".to_string()));
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
@@ -350,8 +350,9 @@ async fn responses_respects_model_info_overrides_from_config() {
let config = Arc::new(config);
let conversation_id = ThreadId::new();
let auth_mode =
AuthManager::from_auth_for_testing(CodexAuth::from_api_key("Test API Key")).get_auth_mode();
let auth_mode = AuthManager::from_auth_for_testing(CodexAuth::from_api_key("Test API Key"))
.auth_mode()
.map(TelemetryAuthMode::from);
let session_source =
SessionSource::SubAgent(SubAgentSource::Other("override-check".to_string()));
let model_info = ModelsManager::construct_model_info_offline(model.as_str(), &config);
+2 -1
View File
@@ -21,6 +21,7 @@ use codex_core::protocol::EventMsg;
use codex_core::protocol::Op;
use codex_core::protocol::SessionSource;
use codex_otel::OtelManager;
use codex_otel::TelemetryAuthMode;
use codex_protocol::ThreadId;
use codex_protocol::config_types::CollaborationMode;
use codex_protocol::config_types::ModeKind;
@@ -1257,7 +1258,7 @@ async fn azure_responses_request_includes_store_and_reasoning_ids() {
model_info.slug.as_str(),
None,
Some("test@test.com".to_string()),
auth_manager.get_auth_mode(),
auth_manager.auth_mode().map(TelemetryAuthMode::from),
false,
"test".to_string(),
SessionSource::Exec,
@@ -14,6 +14,7 @@ use codex_core::features::Feature;
use codex_core::models_manager::manager::ModelsManager;
use codex_core::protocol::SessionSource;
use codex_otel::OtelManager;
use codex_otel::TelemetryAuthMode;
use codex_otel::metrics::MetricsClient;
use codex_otel::metrics::MetricsConfig;
use codex_protocol::ThreadId;
@@ -446,7 +447,7 @@ async fn websocket_harness_with_runtime_metrics(
model_info.slug.as_str(),
None,
Some("test@test.com".to_string()),
auth_manager.get_auth_mode(),
auth_manager.auth_mode().map(TelemetryAuthMode::from),
false,
"test".to_string(),
SessionSource::Exec,
-1
View File
@@ -21,7 +21,6 @@ disable-default-metrics-exporter = []
[dependencies]
chrono = { workspace = true }
codex-app-server-protocol = { workspace = true }
codex-utils-absolute-path = { workspace = true }
codex-utils-string = { workspace = true }
codex-api = { workspace = true }
+7
View File
@@ -31,6 +31,13 @@ pub enum ToolDecisionSource {
User,
}
/// Maps to core AuthMode to avoid a circular dependency on codex-core.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Display)]
pub enum TelemetryAuthMode {
ApiKey,
Chatgpt,
}
#[derive(Debug, Clone)]
pub struct OtelEventMetadata {
pub(crate) conversation_id: ThreadId,
+2 -2
View File
@@ -1,3 +1,4 @@
use crate::TelemetryAuthMode;
use crate::metrics::names::API_CALL_COUNT_METRIC;
use crate::metrics::names::API_CALL_DURATION_METRIC;
use crate::metrics::names::RESPONSES_API_INFERENCE_TIME_DURATION_METRIC;
@@ -15,7 +16,6 @@ use chrono::SecondsFormat;
use chrono::Utc;
use codex_api::ApiError;
use codex_api::ResponseEvent;
use codex_app_server_protocol::AuthMode;
use codex_protocol::ThreadId;
use codex_protocol::config_types::ReasoningSummary;
use codex_protocol::models::ResponseItem;
@@ -57,7 +57,7 @@ impl OtelManager {
slug: &str,
account_id: Option<String>,
account_email: Option<String>,
auth_mode: Option<AuthMode>,
auth_mode: Option<TelemetryAuthMode>,
log_user_prompts: bool,
terminal_type: String,
session_source: SessionSource,
+7 -4
View File
@@ -2,8 +2,8 @@ use crate::harness::attributes_to_map;
use crate::harness::build_metrics_with_defaults;
use crate::harness::find_metric;
use crate::harness::latest_metrics;
use codex_app_server_protocol::AuthMode;
use codex_otel::OtelManager;
use codex_otel::TelemetryAuthMode;
use codex_otel::metrics::Result;
use codex_protocol::ThreadId;
use codex_protocol::protocol::SessionSource;
@@ -22,7 +22,7 @@ fn manager_attaches_metadata_tags_to_metrics() -> Result<()> {
"gpt-5.1",
Some("account-id".to_string()),
None,
Some(AuthMode::ApiKey),
Some(TelemetryAuthMode::ApiKey),
true,
"tty".to_string(),
SessionSource::Cli,
@@ -52,7 +52,10 @@ fn manager_attaches_metadata_tags_to_metrics() -> Result<()> {
"app.version".to_string(),
env!("CARGO_PKG_VERSION").to_string(),
),
("auth_mode".to_string(), AuthMode::ApiKey.to_string()),
(
"auth_mode".to_string(),
TelemetryAuthMode::ApiKey.to_string(),
),
("model".to_string(), "gpt-5.1".to_string()),
("service".to_string(), "codex-cli".to_string()),
("session_source".to_string(), "cli".to_string()),
@@ -73,7 +76,7 @@ fn manager_allows_disabling_metadata_tags() -> Result<()> {
"gpt-4o",
Some("account-id".to_string()),
None,
Some(AuthMode::ApiKey),
Some(TelemetryAuthMode::ApiKey),
true,
"tty".to_string(),
SessionSource::Cli,
+2 -2
View File
@@ -1,7 +1,7 @@
use codex_app_server_protocol::AuthMode;
use codex_otel::OtelManager;
use codex_otel::RuntimeMetricTotals;
use codex_otel::RuntimeMetricsSummary;
use codex_otel::TelemetryAuthMode;
use codex_otel::metrics::MetricsClient;
use codex_otel::metrics::MetricsConfig;
use codex_otel::metrics::Result;
@@ -26,7 +26,7 @@ fn runtime_metrics_summary_collects_tool_api_and_streaming_metrics() -> Result<(
"gpt-5.1",
Some("account-id".to_string()),
None,
Some(AuthMode::ApiKey),
Some(TelemetryAuthMode::ApiKey),
true,
"tty".to_string(),
SessionSource::Cli,
+6 -3
View File
@@ -1,7 +1,7 @@
use crate::harness::attributes_to_map;
use crate::harness::find_metric;
use codex_app_server_protocol::AuthMode;
use codex_otel::OtelManager;
use codex_otel::TelemetryAuthMode;
use codex_otel::metrics::MetricsClient;
use codex_otel::metrics::MetricsConfig;
use codex_otel::metrics::Result;
@@ -75,7 +75,7 @@ fn manager_snapshot_metrics_collects_without_shutdown() -> Result<()> {
"gpt-5.1",
Some("account-id".to_string()),
None,
Some(AuthMode::ApiKey),
Some(TelemetryAuthMode::ApiKey),
true,
"tty".to_string(),
SessionSource::Cli,
@@ -107,7 +107,10 @@ fn manager_snapshot_metrics_collects_without_shutdown() -> Result<()> {
"app.version".to_string(),
env!("CARGO_PKG_VERSION").to_string(),
),
("auth_mode".to_string(), AuthMode::ApiKey.to_string()),
(
"auth_mode".to_string(),
TelemetryAuthMode::ApiKey.to_string(),
),
("model".to_string(), "gpt-5.1".to_string()),
("service".to_string(), "codex-cli".to_string()),
("session_source".to_string(), "cli".to_string()),
+5 -1
View File
@@ -60,6 +60,7 @@ use codex_core::protocol::TokenUsage;
#[cfg(target_os = "windows")]
use codex_core::windows_sandbox::WindowsSandboxLevelExt;
use codex_otel::OtelManager;
use codex_otel::TelemetryAuthMode;
use codex_protocol::ThreadId;
use codex_protocol::config_types::Personality;
#[cfg(target_os = "windows")]
@@ -975,13 +976,16 @@ impl App {
} else {
FeedbackAudience::External
};
let auth_mode = auth_ref
.map(CodexAuth::auth_mode)
.map(TelemetryAuthMode::from);
let otel_manager = OtelManager::new(
ThreadId::new(),
model.as_str(),
model.as_str(),
auth_ref.and_then(CodexAuth::get_account_id),
auth_ref.and_then(CodexAuth::get_account_email),
auth_ref.map(CodexAuth::api_auth_mode),
auth_mode,
config.otel.log_user_prompt,
codex_core::terminal::user_agent(),
SessionSource::Cli,
+2 -2
View File
@@ -7,7 +7,6 @@ use additional_dirs::add_dir_warning_message;
use app::App;
pub use app::AppExitInfo;
pub use app::ExitReason;
use codex_app_server_protocol::AuthMode;
use codex_cloud_requirements::cloud_requirements_loader;
use codex_common::oss::ensure_oss_provider_ready;
use codex_common::oss::get_default_model_for_oss_provider;
@@ -16,6 +15,7 @@ use codex_core::CodexAuth;
use codex_core::INTERACTIVE_SESSION_SOURCES;
use codex_core::RolloutRecorder;
use codex_core::ThreadSortKey;
use codex_core::auth::AuthMode;
use codex_core::auth::enforce_login_restrictions;
use codex_core::config::Config;
use codex_core::config::ConfigBuilder;
@@ -841,7 +841,7 @@ fn get_login_status(config: &Config) -> LoginStatus {
// to refresh the token. Block on it.
let codex_home = config.codex_home.clone();
match CodexAuth::from_auth_storage(&codex_home, config.cli_auth_credentials_store_mode) {
Ok(Some(auth)) => LoginStatus::AuthMode(auth.api_auth_mode()),
Ok(Some(auth)) => LoginStatus::AuthMode(auth.auth_mode()),
Ok(None) => LoginStatus::NotAuthenticated,
Err(err) => {
error!("Failed to read auth.json: {err}");
+2 -5
View File
@@ -30,7 +30,7 @@ use ratatui::widgets::Paragraph;
use ratatui::widgets::WidgetRef;
use ratatui::widgets::Wrap;
use codex_app_server_protocol::AuthMode;
use codex_core::auth::AuthMode;
use codex_protocol::config_types::ForcedLoginMethod;
use std::sync::RwLock;
@@ -661,10 +661,7 @@ impl AuthModeWidget {
}
fn handle_existing_chatgpt_login(&mut self) -> bool {
if matches!(
self.login_status,
LoginStatus::AuthMode(AuthMode::Chatgpt | AuthMode::ChatgptAuthTokens)
) {
if matches!(self.login_status, LoginStatus::AuthMode(AuthMode::Chatgpt)) {
*self.sign_in_state.write().unwrap() = SignInState::ChatGptSuccess;
self.request_frame.schedule_frame();
true
+4 -4
View File
@@ -3,7 +3,7 @@ use crate::text_formatting;
use chrono::DateTime;
use chrono::Local;
use codex_core::AuthManager;
use codex_core::CodexAuth;
use codex_core::auth::AuthMode as CoreAuthMode;
use codex_core::config::Config;
use codex_core::project_doc::discover_project_doc_paths;
use codex_protocol::account::PlanType;
@@ -90,15 +90,15 @@ pub(crate) fn compose_account_display(
) -> Option<StatusAccountDisplay> {
let auth = auth_manager.auth_cached()?;
match auth {
CodexAuth::Chatgpt(_) | CodexAuth::ChatgptAuthTokens(_) => {
match auth.auth_mode() {
CoreAuthMode::ApiKey => Some(StatusAccountDisplay::ApiKey),
CoreAuthMode::Chatgpt => {
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()));
Some(StatusAccountDisplay::ChatGpt { email, plan })
}
CodexAuth::ApiKey(_) => Some(StatusAccountDisplay::ApiKey),
}
}