diff --git a/codex-rs/chatgpt/src/chatgpt_token.rs b/codex-rs/chatgpt/src/chatgpt_token.rs index 55ebc22a..c674afbc 100644 --- a/codex-rs/chatgpt/src/chatgpt_token.rs +++ b/codex-rs/chatgpt/src/chatgpt_token.rs @@ -1,3 +1,4 @@ +use codex_login::CodexAuth; use std::path::Path; use std::sync::LazyLock; use std::sync::RwLock; @@ -18,7 +19,7 @@ pub fn set_chatgpt_token_data(value: TokenData) { /// Initialize the ChatGPT token from auth.json file pub async fn init_chatgpt_token_from_auth(codex_home: &Path) -> std::io::Result<()> { - let auth = codex_login::load_auth(codex_home)?; + let auth = CodexAuth::from_codex_home(codex_home)?; if let Some(auth) = auth { let token_data = auth.get_token_data().await?; set_chatgpt_token_data(token_data); diff --git a/codex-rs/cli/src/login.rs b/codex-rs/cli/src/login.rs index 3881a1ce..1a70bd27 100644 --- a/codex-rs/cli/src/login.rs +++ b/codex-rs/cli/src/login.rs @@ -4,8 +4,8 @@ use codex_common::CliConfigOverrides; use codex_core::config::Config; use codex_core::config::ConfigOverrides; use codex_login::AuthMode; +use codex_login::CodexAuth; use codex_login::OPENAI_API_KEY_ENV_VAR; -use codex_login::load_auth; use codex_login::login_with_api_key; use codex_login::login_with_chatgpt; use codex_login::logout; @@ -47,7 +47,7 @@ pub async fn run_login_with_api_key( pub async fn run_login_status(cli_config_overrides: CliConfigOverrides) -> ! { let config = load_config_or_exit(cli_config_overrides); - match load_auth(&config.codex_home) { + match CodexAuth::from_codex_home(&config.codex_home) { Ok(Some(auth)) => match auth.mode { AuthMode::ApiKey => match auth.get_token().await { Ok(api_key) => { diff --git a/codex-rs/cli/src/proto.rs b/codex-rs/cli/src/proto.rs index 291e1680..6c1de7ea 100644 --- a/codex-rs/cli/src/proto.rs +++ b/codex-rs/cli/src/proto.rs @@ -9,7 +9,7 @@ use codex_core::config::Config; use codex_core::config::ConfigOverrides; use codex_core::protocol::Submission; use codex_core::util::notify_on_sigint; -use codex_login::load_auth; +use codex_login::CodexAuth; use tokio::io::AsyncBufReadExt; use tokio::io::BufReader; use tracing::error; @@ -36,7 +36,7 @@ pub async fn run_main(opts: ProtoCli) -> anyhow::Result<()> { .map_err(anyhow::Error::msg)?; let config = Config::load_with_cli_overrides(overrides_vec, ConfigOverrides::default())?; - let auth = load_auth(&config.codex_home)?; + let auth = CodexAuth::from_codex_home(&config.codex_home)?; let ctrl_c = notify_on_sigint(); let CodexSpawnOk { codex, .. } = Codex::spawn(config, auth, ctrl_c.clone()).await?; let codex = Arc::new(codex); diff --git a/codex-rs/core/src/codex_wrapper.rs b/codex-rs/core/src/codex_wrapper.rs index 1e26a9eb..dc10ec8d 100644 --- a/codex-rs/core/src/codex_wrapper.rs +++ b/codex-rs/core/src/codex_wrapper.rs @@ -6,7 +6,7 @@ use crate::config::Config; use crate::protocol::Event; use crate::protocol::EventMsg; use crate::util::notify_on_sigint; -use codex_login::load_auth; +use codex_login::CodexAuth; use tokio::sync::Notify; use uuid::Uuid; @@ -26,7 +26,7 @@ pub struct CodexConversation { /// that callers can surface the information to the UI. pub async fn init_codex(config: Config) -> anyhow::Result { let ctrl_c = notify_on_sigint(); - let auth = load_auth(&config.codex_home)?; + let auth = CodexAuth::from_codex_home(&config.codex_home)?; let CodexSpawnOk { codex, init_id, diff --git a/codex-rs/login/src/lib.rs b/codex-rs/login/src/lib.rs index 36a78aaa..8c8ad75b 100644 --- a/codex-rs/login/src/lib.rs +++ b/codex-rs/login/src/lib.rs @@ -61,6 +61,12 @@ impl CodexAuth { } } + /// Loads the available auth information from the auth.json or + /// OPENAI_API_KEY environment variable. + pub fn from_codex_home(codex_home: &Path) -> std::io::Result> { + load_auth(codex_home, true) + } + pub async fn get_token_data(&self) -> Result { #[expect(clippy::unwrap_used)] let auth_dot_json = self.auth_dot_json.lock().unwrap().clone(); @@ -152,12 +158,7 @@ impl CodexAuth { } } -// Loads the available auth information from the auth.json or OPENAI_API_KEY environment variable. -pub fn load_auth(codex_home: &Path) -> std::io::Result> { - _load_auth(codex_home, true) -} - -fn _load_auth(codex_home: &Path, include_env_var: bool) -> std::io::Result> { +fn load_auth(codex_home: &Path, include_env_var: bool) -> std::io::Result> { let auth_file = get_auth_file(codex_home); let auth_dot_json = try_read_auth_json(&auth_file).ok(); @@ -433,7 +434,7 @@ mod tests { fn writes_api_key_and_loads_auth() { let dir = tempdir().unwrap(); login_with_api_key(dir.path(), "sk-test-key").unwrap(); - let auth = _load_auth(dir.path(), false).unwrap().unwrap(); + let auth = load_auth(dir.path(), false).unwrap().unwrap(); assert_eq!(auth.mode, AuthMode::ApiKey); assert_eq!(auth.api_key.as_deref(), Some("sk-test-key")); } @@ -446,7 +447,7 @@ mod tests { let env_var = std::env::var(OPENAI_API_KEY_ENV_VAR); if let Ok(env_var) = env_var { - let auth = _load_auth(dir.path(), true).unwrap().unwrap(); + let auth = load_auth(dir.path(), true).unwrap().unwrap(); assert_eq!(auth.mode, AuthMode::ApiKey); assert_eq!(auth.api_key, Some(env_var)); } @@ -505,7 +506,7 @@ mod tests { mode, auth_dot_json, auth_file, - } = _load_auth(dir.path(), false).unwrap().unwrap(); + } = load_auth(dir.path(), false).unwrap().unwrap(); assert_eq!(None, api_key); assert_eq!(AuthMode::ChatGPT, mode); assert_eq!(dir.path().join("auth.json"), auth_file); @@ -570,7 +571,7 @@ mod tests { ) .unwrap(); - let auth = _load_auth(dir.path(), false).unwrap().unwrap(); + let auth = load_auth(dir.path(), false).unwrap().unwrap(); assert_eq!(auth.mode, AuthMode::ApiKey); assert_eq!(auth.api_key, Some("sk-test-key".to_string())); diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs index a5cfe283..e15a235a 100644 --- a/codex-rs/tui/src/lib.rs +++ b/codex-rs/tui/src/lib.rs @@ -12,7 +12,7 @@ use codex_core::config::load_config_as_toml_with_cli_overrides; use codex_core::config_types::SandboxMode; use codex_core::protocol::AskForApproval; use codex_core::protocol::SandboxPolicy; -use codex_login::load_auth; +use codex_login::CodexAuth; use codex_ollama::DEFAULT_OSS_MODEL; use log_layer::TuiLogLayer; use std::fs::OpenOptions; @@ -304,7 +304,7 @@ fn should_show_login_screen(config: &Config) -> bool { // Reading the OpenAI API key is an async operation because it may need // to refresh the token. Block on it. let codex_home = config.codex_home.clone(); - match load_auth(&codex_home) { + match CodexAuth::from_codex_home(&codex_home) { Ok(Some(_)) => false, Ok(None) => true, Err(err) => {