mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
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:
committed by
GitHub
Unverified
parent
5c0fd62ff1
commit
3582b74d01
Generated
-1
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user