refactor(chatgpt): use CodexAuth for backend auth

This commit is contained in:
James Peter
2026-04-25 09:28:18 +10:00
parent 0fbda5328f
commit e5b7e04b46
9 changed files with 26 additions and 59 deletions
@@ -96,6 +96,7 @@ macro_rules! v2_enum_from_core {
pub enum CodexErrorInfo {
ContextWindowExceeded,
UsageLimitExceeded,
CyberPolicy,
ModelCap {
model: String,
reset_after_seconds: Option<u64>,
@@ -136,6 +137,7 @@ impl From<CoreCodexErrorInfo> for CodexErrorInfo {
match value {
CoreCodexErrorInfo::ContextWindowExceeded => CodexErrorInfo::ContextWindowExceeded,
CoreCodexErrorInfo::UsageLimitExceeded => CodexErrorInfo::UsageLimitExceeded,
CoreCodexErrorInfo::CyberPolicy => CodexErrorInfo::CyberPolicy,
CoreCodexErrorInfo::ModelCap {
model,
reset_after_seconds,
-4
View File
@@ -4,8 +4,6 @@ use clap::Parser;
use code_common::CliConfigOverrides;
use code_core::config::Config;
use code_core::config::ConfigOverrides;
use crate::chatgpt_token::init_chatgpt_token_from_auth;
use crate::get_task::GetTaskResponse;
use crate::get_task::OutputItem;
use crate::get_task::PrOutputItem;
@@ -31,8 +29,6 @@ pub async fn run_apply_command(
ConfigOverrides::default(),
)?;
init_chatgpt_token_from_auth(&config.code_home, &config.responses_originator_header).await?;
let task_response = get_task(&config, apply_cli.task_id).await?;
apply_diff_from_task(task_response, cwd).await
}
+15 -9
View File
@@ -1,7 +1,6 @@
use code_core::config::Config;
use crate::chatgpt_token::get_chatgpt_token_data;
use crate::chatgpt_token::init_chatgpt_token_from_auth;
use code_core::CodexAuth;
use code_app_server_protocol::AuthMode;
use anyhow::Context;
use serde::de::DeserializeOwned;
@@ -12,23 +11,30 @@ pub(crate) async fn chatgpt_get_request<T: DeserializeOwned>(
path: String,
) -> anyhow::Result<T> {
let chatgpt_base_url = &config.chatgpt_base_url;
init_chatgpt_token_from_auth(&config.code_home, &config.responses_originator_header).await?;
let auth = CodexAuth::from_code_home(
&config.code_home,
AuthMode::ChatGPT,
&config.responses_originator_header,
)?
.ok_or_else(|| anyhow::anyhow!("ChatGPT auth not available"))?;
anyhow::ensure!(
auth.uses_codex_backend(),
"ChatGPT backend requests require Codex backend auth"
);
// Make direct HTTP request to ChatGPT backend API with the token
let client = code_core::http_client::build_http_client();
let url = format!("{chatgpt_base_url}{path}");
let token =
get_chatgpt_token_data().ok_or_else(|| anyhow::anyhow!("ChatGPT token not available"))?;
let token = auth.get_token_data().await?;
let account_id = token.account_id.ok_or_else(|| {
anyhow::anyhow!("ChatGPT account ID not available, please re-run `code login`")
});
})?;
let mut request = client
.get(&url)
.bearer_auth(&token.access_token)
.header("chatgpt-account-id", account_id?)
.header("chatgpt-account-id", account_id)
.header("Content-Type", "application/json");
if token.id_token.is_fedramp_account() {
request = request.header("X-OpenAI-Fedramp", "true");
-32
View File
@@ -1,32 +0,0 @@
use code_core::CodexAuth;
use code_app_server_protocol::AuthMode;
use std::path::Path;
use std::sync::LazyLock;
use std::sync::RwLock;
use code_core::token_data::TokenData;
static CHATGPT_TOKEN: LazyLock<RwLock<Option<TokenData>>> = LazyLock::new(|| RwLock::new(None));
pub fn get_chatgpt_token_data() -> Option<TokenData> {
CHATGPT_TOKEN.read().ok()?.clone()
}
pub fn set_chatgpt_token_data(value: TokenData) {
if let Ok(mut guard) = CHATGPT_TOKEN.write() {
*guard = Some(value);
}
}
/// Initialize the ChatGPT token from auth.json file
pub async fn init_chatgpt_token_from_auth(
code_home: &Path,
originator: &str,
) -> std::io::Result<()> {
let auth = CodexAuth::from_code_home(code_home, AuthMode::ChatGPT, originator)?;
if let Some(auth) = auth {
let token_data = auth.get_token_data().await?;
set_chatgpt_token_data(token_data);
}
Ok(())
}
-1
View File
@@ -1,4 +1,3 @@
pub mod apply_command;
mod chatgpt_client;
mod chatgpt_token;
pub mod get_task;
+5 -1
View File
@@ -252,8 +252,12 @@ impl CodexAuth {
.is_some_and(|t| t.id_token.is_fedramp_account())
}
pub fn uses_codex_backend(&self) -> bool {
matches!(self.mode, AuthMode::ChatGPT | AuthMode::ChatgptAuthTokens)
}
pub fn supports_pro_only_models(&self) -> bool {
self.mode.is_chatgpt()
self.uses_codex_backend()
&& self
.get_plan_type()
.is_some_and(|plan| plan.eq_ignore_ascii_case("pro"))
+1 -4
View File
@@ -439,10 +439,7 @@ impl ModelProviderInfo {
}
pub(crate) fn get_full_url(&self, auth: &Option<CodexAuth>) -> String {
let default_base_url = if auth
.as_ref()
.is_some_and(|auth| auth.mode.is_chatgpt())
{
let default_base_url = if auth.as_ref().is_some_and(CodexAuth::uses_codex_backend) {
"https://chatgpt.com/backend-api/codex"
} else {
"https://api.openai.com/v1"
+2 -8
View File
@@ -179,7 +179,7 @@ impl RemoteModelsManager {
}
if let Some(auth) = auth.as_ref()
&& auth.mode.is_chatgpt()
&& auth.uses_codex_backend()
&& let Some(account_id) = auth.get_account_id()
{
request = request.header("chatgpt-account-id", account_id);
@@ -317,13 +317,7 @@ impl RemoteModelsManager {
fn models_url(&self, auth: &Option<CodexAuth>) -> crate::error::Result<Url> {
let base_url = self.provider.base_url.clone().unwrap_or_else(|| {
if matches!(
auth,
Some(CodexAuth {
mode: AuthMode::ChatGPT | AuthMode::ChatgptAuthTokens,
..
})
) {
if auth.as_ref().is_some_and(CodexAuth::uses_codex_backend) {
"https://chatgpt.com/backend-api/codex".to_string()
} else {
"https://api.openai.com/v1".to_string()
+1
View File
@@ -1044,6 +1044,7 @@ pub enum AgentStatus {
pub enum CodexErrorInfo {
ContextWindowExceeded,
UsageLimitExceeded,
CyberPolicy,
ModelCap {
model: String,
reset_after_seconds: Option<u64>,