Skip to content

Commit c09e131

Browse files
authored
Set originator for codex exec (#4485)
Distinct from the main CLI.
1 parent ea82f86 commit c09e131

File tree

5 files changed

+44
-11
lines changed

5 files changed

+44
-11
lines changed

codex-rs/core/src/default_client.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::spawn::CODEX_SANDBOX_ENV_VAR;
22
use reqwest::header::HeaderValue;
33
use std::sync::LazyLock;
44
use std::sync::Mutex;
5+
use std::sync::OnceLock;
56

67
/// Set this to add a suffix to the User-Agent string.
78
///
@@ -26,8 +27,15 @@ pub struct Originator {
2627
pub value: String,
2728
pub header_value: HeaderValue,
2829
}
30+
static ORIGINATOR: OnceLock<Originator> = OnceLock::new();
2931

30-
pub static ORIGINATOR: LazyLock<Originator> = LazyLock::new(|| {
32+
#[derive(Debug)]
33+
pub enum SetOriginatorError {
34+
InvalidHeaderValue,
35+
AlreadyInitialized,
36+
}
37+
38+
fn init_originator_from_env() -> Originator {
3139
let default = "codex_cli_rs";
3240
let value = std::env::var(CODEX_INTERNAL_ORIGINATOR_OVERRIDE_ENV_VAR)
3341
.unwrap_or_else(|_| default.to_string());
@@ -45,14 +53,34 @@ pub static ORIGINATOR: LazyLock<Originator> = LazyLock::new(|| {
4553
}
4654
}
4755
}
48-
});
56+
}
57+
58+
fn build_originator(value: String) -> Result<Originator, SetOriginatorError> {
59+
let header_value =
60+
HeaderValue::from_str(&value).map_err(|_| SetOriginatorError::InvalidHeaderValue)?;
61+
Ok(Originator {
62+
value,
63+
header_value,
64+
})
65+
}
66+
67+
pub fn set_default_originator(value: &str) -> Result<(), SetOriginatorError> {
68+
let originator = build_originator(value.to_string())?;
69+
ORIGINATOR
70+
.set(originator)
71+
.map_err(|_| SetOriginatorError::AlreadyInitialized)
72+
}
73+
74+
pub fn originator() -> &'static Originator {
75+
ORIGINATOR.get_or_init(init_originator_from_env)
76+
}
4977

5078
pub fn get_codex_user_agent() -> String {
5179
let build_version = env!("CARGO_PKG_VERSION");
5280
let os_info = os_info::get();
5381
let prefix = format!(
5482
"{}/{build_version} ({} {}; {}) {}",
55-
ORIGINATOR.value.as_str(),
83+
originator().value.as_str(),
5684
os_info.os_type(),
5785
os_info.version(),
5886
os_info.architecture().unwrap_or("unknown"),
@@ -100,7 +128,7 @@ fn sanitize_user_agent(candidate: String, fallback: &str) -> String {
100128
tracing::warn!(
101129
"Falling back to default Codex originator because base user agent string is invalid"
102130
);
103-
ORIGINATOR.value.clone()
131+
originator().value.clone()
104132
}
105133
}
106134

@@ -109,7 +137,7 @@ pub fn create_client() -> reqwest::Client {
109137
use reqwest::header::HeaderMap;
110138

111139
let mut headers = HeaderMap::new();
112-
headers.insert("originator", ORIGINATOR.header_value.clone());
140+
headers.insert("originator", originator().header_value.clone());
113141
let ua = get_codex_user_agent();
114142

115143
let mut builder = reqwest::Client::builder()

codex-rs/core/src/otel_init.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::config::Config;
22
use crate::config_types::OtelExporterKind as Kind;
33
use crate::config_types::OtelHttpProtocol as Protocol;
4-
use crate::default_client::ORIGINATOR;
4+
use crate::default_client::originator;
55
use codex_otel::config::OtelExporter;
66
use codex_otel::config::OtelHttpProtocol;
77
use codex_otel::config::OtelSettings;
@@ -46,7 +46,7 @@ pub fn build_provider(
4646
};
4747

4848
OtelProvider::from(&OtelSettings {
49-
service_name: ORIGINATOR.value.to_owned(),
49+
service_name: originator().value.to_owned(),
5050
service_version: service_version.to_string(),
5151
codex_home: config.codex_home.clone(),
5252
environment: config.otel.environment.to_string(),

codex-rs/core/src/rollout/recorder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use super::list::Cursor;
2424
use super::list::get_conversations;
2525
use super::policy::is_persisted_response_item;
2626
use crate::config::Config;
27-
use crate::default_client::ORIGINATOR;
27+
use crate::default_client::originator;
2828
use crate::git_info::collect_git_info;
2929
use codex_protocol::protocol::InitialHistory;
3030
use codex_protocol::protocol::ResumedHistory;
@@ -124,7 +124,7 @@ impl RolloutRecorder {
124124
id: session_id,
125125
timestamp,
126126
cwd: config.cwd.clone(),
127-
originator: ORIGINATOR.value.clone(),
127+
originator: originator().value.clone(),
128128
cli_version: env!("CARGO_PKG_VERSION").to_string(),
129129
instructions,
130130
}),

codex-rs/exec/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,14 @@ use tracing_subscriber::prelude::*;
3838
use crate::cli::Command as ExecCommand;
3939
use crate::event_processor::CodexStatus;
4040
use crate::event_processor::EventProcessor;
41+
use codex_core::default_client::set_default_originator;
4142
use codex_core::find_conversation_path_by_id_str;
4243

4344
pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> anyhow::Result<()> {
45+
if let Err(err) = set_default_originator("codex_exec") {
46+
tracing::warn!(?err, "Failed to set codex exec originator override {err:?}");
47+
}
48+
4449
let Cli {
4550
command,
4651
images,

codex-rs/login/src/server.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use base64::Engine;
1616
use chrono::Utc;
1717
use codex_core::auth::AuthDotJson;
1818
use codex_core::auth::get_auth_file;
19-
use codex_core::default_client::ORIGINATOR;
19+
use codex_core::default_client::originator;
2020
use codex_core::token_data::TokenData;
2121
use codex_core::token_data::parse_id_token;
2222
use rand::RngCore;
@@ -315,7 +315,7 @@ fn build_authorize_url(
315315
("id_token_add_organizations", "true"),
316316
("codex_cli_simplified_flow", "true"),
317317
("state", state),
318-
("originator", ORIGINATOR.value.as_str()),
318+
("originator", originator().value.as_str()),
319319
];
320320
let qs = query
321321
.into_iter()

0 commit comments

Comments
 (0)