Set originator for codex exec (#4485)

Distinct from the main CLI.
This commit is contained in:
pakrym-oai
2025-09-29 20:59:19 -07:00
committed by GitHub
parent ea82f86662
commit c09e131653
5 changed files with 44 additions and 11 deletions

View File

@@ -2,6 +2,7 @@ use crate::spawn::CODEX_SANDBOX_ENV_VAR;
use reqwest::header::HeaderValue; use reqwest::header::HeaderValue;
use std::sync::LazyLock; use std::sync::LazyLock;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::OnceLock;
/// Set this to add a suffix to the User-Agent string. /// Set this to add a suffix to the User-Agent string.
/// ///
@@ -26,8 +27,15 @@ pub struct Originator {
pub value: String, pub value: String,
pub header_value: HeaderValue, pub header_value: HeaderValue,
} }
static ORIGINATOR: OnceLock<Originator> = OnceLock::new();
pub static ORIGINATOR: LazyLock<Originator> = LazyLock::new(|| { #[derive(Debug)]
pub enum SetOriginatorError {
InvalidHeaderValue,
AlreadyInitialized,
}
fn init_originator_from_env() -> Originator {
let default = "codex_cli_rs"; let default = "codex_cli_rs";
let value = std::env::var(CODEX_INTERNAL_ORIGINATOR_OVERRIDE_ENV_VAR) let value = std::env::var(CODEX_INTERNAL_ORIGINATOR_OVERRIDE_ENV_VAR)
.unwrap_or_else(|_| default.to_string()); .unwrap_or_else(|_| default.to_string());
@@ -45,14 +53,34 @@ pub static ORIGINATOR: LazyLock<Originator> = LazyLock::new(|| {
} }
} }
} }
}); }
fn build_originator(value: String) -> Result<Originator, SetOriginatorError> {
let header_value =
HeaderValue::from_str(&value).map_err(|_| SetOriginatorError::InvalidHeaderValue)?;
Ok(Originator {
value,
header_value,
})
}
pub fn set_default_originator(value: &str) -> Result<(), SetOriginatorError> {
let originator = build_originator(value.to_string())?;
ORIGINATOR
.set(originator)
.map_err(|_| SetOriginatorError::AlreadyInitialized)
}
pub fn originator() -> &'static Originator {
ORIGINATOR.get_or_init(init_originator_from_env)
}
pub fn get_codex_user_agent() -> String { pub fn get_codex_user_agent() -> String {
let build_version = env!("CARGO_PKG_VERSION"); let build_version = env!("CARGO_PKG_VERSION");
let os_info = os_info::get(); let os_info = os_info::get();
let prefix = format!( let prefix = format!(
"{}/{build_version} ({} {}; {}) {}", "{}/{build_version} ({} {}; {}) {}",
ORIGINATOR.value.as_str(), originator().value.as_str(),
os_info.os_type(), os_info.os_type(),
os_info.version(), os_info.version(),
os_info.architecture().unwrap_or("unknown"), os_info.architecture().unwrap_or("unknown"),
@@ -100,7 +128,7 @@ fn sanitize_user_agent(candidate: String, fallback: &str) -> String {
tracing::warn!( tracing::warn!(
"Falling back to default Codex originator because base user agent string is invalid" "Falling back to default Codex originator because base user agent string is invalid"
); );
ORIGINATOR.value.clone() originator().value.clone()
} }
} }
@@ -109,7 +137,7 @@ pub fn create_client() -> reqwest::Client {
use reqwest::header::HeaderMap; use reqwest::header::HeaderMap;
let mut headers = HeaderMap::new(); let mut headers = HeaderMap::new();
headers.insert("originator", ORIGINATOR.header_value.clone()); headers.insert("originator", originator().header_value.clone());
let ua = get_codex_user_agent(); let ua = get_codex_user_agent();
let mut builder = reqwest::Client::builder() let mut builder = reqwest::Client::builder()

View File

@@ -1,7 +1,7 @@
use crate::config::Config; use crate::config::Config;
use crate::config_types::OtelExporterKind as Kind; use crate::config_types::OtelExporterKind as Kind;
use crate::config_types::OtelHttpProtocol as Protocol; use crate::config_types::OtelHttpProtocol as Protocol;
use crate::default_client::ORIGINATOR; use crate::default_client::originator;
use codex_otel::config::OtelExporter; use codex_otel::config::OtelExporter;
use codex_otel::config::OtelHttpProtocol; use codex_otel::config::OtelHttpProtocol;
use codex_otel::config::OtelSettings; use codex_otel::config::OtelSettings;
@@ -46,7 +46,7 @@ pub fn build_provider(
}; };
OtelProvider::from(&OtelSettings { OtelProvider::from(&OtelSettings {
service_name: ORIGINATOR.value.to_owned(), service_name: originator().value.to_owned(),
service_version: service_version.to_string(), service_version: service_version.to_string(),
codex_home: config.codex_home.clone(), codex_home: config.codex_home.clone(),
environment: config.otel.environment.to_string(), environment: config.otel.environment.to_string(),

View File

@@ -24,7 +24,7 @@ use super::list::Cursor;
use super::list::get_conversations; use super::list::get_conversations;
use super::policy::is_persisted_response_item; use super::policy::is_persisted_response_item;
use crate::config::Config; use crate::config::Config;
use crate::default_client::ORIGINATOR; use crate::default_client::originator;
use crate::git_info::collect_git_info; use crate::git_info::collect_git_info;
use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::InitialHistory;
use codex_protocol::protocol::ResumedHistory; use codex_protocol::protocol::ResumedHistory;
@@ -124,7 +124,7 @@ impl RolloutRecorder {
id: session_id, id: session_id,
timestamp, timestamp,
cwd: config.cwd.clone(), cwd: config.cwd.clone(),
originator: ORIGINATOR.value.clone(), originator: originator().value.clone(),
cli_version: env!("CARGO_PKG_VERSION").to_string(), cli_version: env!("CARGO_PKG_VERSION").to_string(),
instructions, instructions,
}), }),

View File

@@ -38,9 +38,14 @@ use tracing_subscriber::prelude::*;
use crate::cli::Command as ExecCommand; use crate::cli::Command as ExecCommand;
use crate::event_processor::CodexStatus; use crate::event_processor::CodexStatus;
use crate::event_processor::EventProcessor; use crate::event_processor::EventProcessor;
use codex_core::default_client::set_default_originator;
use codex_core::find_conversation_path_by_id_str; use codex_core::find_conversation_path_by_id_str;
pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> anyhow::Result<()> { pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> anyhow::Result<()> {
if let Err(err) = set_default_originator("codex_exec") {
tracing::warn!(?err, "Failed to set codex exec originator override {err:?}");
}
let Cli { let Cli {
command, command,
images, images,

View File

@@ -16,7 +16,7 @@ use base64::Engine;
use chrono::Utc; use chrono::Utc;
use codex_core::auth::AuthDotJson; use codex_core::auth::AuthDotJson;
use codex_core::auth::get_auth_file; use codex_core::auth::get_auth_file;
use codex_core::default_client::ORIGINATOR; use codex_core::default_client::originator;
use codex_core::token_data::TokenData; use codex_core::token_data::TokenData;
use codex_core::token_data::parse_id_token; use codex_core::token_data::parse_id_token;
use rand::RngCore; use rand::RngCore;
@@ -315,7 +315,7 @@ fn build_authorize_url(
("id_token_add_organizations", "true"), ("id_token_add_organizations", "true"),
("codex_cli_simplified_flow", "true"), ("codex_cli_simplified_flow", "true"),
("state", state), ("state", state),
("originator", ORIGINATOR.value.as_str()), ("originator", originator().value.as_str()),
]; ];
let qs = query let qs = query
.into_iter() .into_iter()