Extract codex-analytics crate (#15748)

## Summary
- move the analytics events client into codex-analytics
- update codex-core and app-server callsites to use the new crate

## Testing
- CI

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Ahmed Ibrahim
2026-03-25 11:08:05 -07:00
committed by GitHub
Unverified
parent 2bb1027e37
commit d273efc0f3
17 changed files with 244 additions and 138 deletions
+17
View File
@@ -1384,6 +1384,22 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9b18233253483ce2f65329a24072ec414db782531bdbb7d0bbc4bd2ce6b7e21"
[[package]]
name = "codex-analytics"
version = "0.0.0"
dependencies = [
"codex-git-utils",
"codex-login",
"codex-plugin",
"codex-protocol",
"pretty_assertions",
"serde",
"serde_json",
"sha1",
"tokio",
"tracing",
]
[[package]]
name = "codex-ansi-escape"
version = "0.0.0"
@@ -1869,6 +1885,7 @@ dependencies = [
"chardetng",
"chrono",
"clap",
"codex-analytics",
"codex-api",
"codex-app-server-protocol",
"codex-apply-patch",
+2
View File
@@ -1,5 +1,6 @@
[workspace]
members = [
"analytics",
"backend-client",
"ansi-escape",
"async-utils",
@@ -98,6 +99,7 @@ license = "Apache-2.0"
# Internal
app_test_support = { path = "app-server/tests/common" }
codex-ansi-escape = { path = "ansi-escape" }
codex-analytics = { path = "analytics" }
codex-api = { path = "codex-api" }
codex-artifacts = { path = "artifacts" }
codex-code-mode = { path = "code-mode" }
+6
View File
@@ -0,0 +1,6 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "analytics",
crate_name = "codex_analytics",
)
+30
View File
@@ -0,0 +1,30 @@
[package]
edition.workspace = true
license.workspace = true
name = "codex-analytics"
version.workspace = true
[lib]
doctest = false
name = "codex_analytics"
path = "src/lib.rs"
[lints]
workspace = true
[dependencies]
codex-git-utils = { workspace = true }
codex-login = { workspace = true }
codex-plugin = { workspace = true }
codex-protocol = { workspace = true }
serde = { workspace = true, features = ["derive"] }
sha1 = { workspace = true }
tokio = { workspace = true, features = [
"macros",
"rt-multi-thread",
] }
tracing = { workspace = true, features = ["log"] }
[dev-dependencies]
pretty_assertions = { workspace = true }
serde_json = { workspace = true }
@@ -1,9 +1,9 @@
use crate::AuthManager;
use crate::config::Config;
use crate::default_client::create_client;
use crate::plugins::PluginTelemetryMetadata;
use codex_git_utils::collect_git_info;
use codex_git_utils::get_git_repo_root;
use codex_login::AuthManager;
use codex_login::default_client::create_client;
use codex_login::default_client::originator;
use codex_plugin::PluginTelemetryMetadata;
use codex_protocol::protocol::SkillScope;
use serde::Serialize;
use sha1::Digest;
@@ -17,13 +17,13 @@ use std::time::Duration;
use tokio::sync::mpsc;
#[derive(Clone)]
pub(crate) struct TrackEventsContext {
pub(crate) model_slug: String,
pub(crate) thread_id: String,
pub(crate) turn_id: String,
pub struct TrackEventsContext {
pub model_slug: String,
pub thread_id: String,
pub turn_id: String,
}
pub(crate) fn build_track_events_context(
pub fn build_track_events_context(
model_slug: String,
thread_id: String,
turn_id: String,
@@ -36,24 +36,24 @@ pub(crate) fn build_track_events_context(
}
#[derive(Clone, Debug)]
pub(crate) struct SkillInvocation {
pub(crate) skill_name: String,
pub(crate) skill_scope: SkillScope,
pub(crate) skill_path: PathBuf,
pub(crate) invocation_type: InvocationType,
pub struct SkillInvocation {
pub skill_name: String,
pub skill_scope: SkillScope,
pub skill_path: PathBuf,
pub invocation_type: InvocationType,
}
#[derive(Clone, Copy, Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub(crate) enum InvocationType {
pub enum InvocationType {
Explicit,
Implicit,
}
pub(crate) struct AppInvocation {
pub(crate) connector_id: Option<String>,
pub(crate) app_name: Option<String>,
pub(crate) invocation_type: Option<InvocationType>,
pub struct AppInvocation {
pub connector_id: Option<String>,
pub app_name: Option<String>,
pub invocation_type: Option<InvocationType>,
}
#[derive(Clone)]
@@ -66,38 +66,38 @@ pub(crate) struct AnalyticsEventsQueue {
#[derive(Clone)]
pub struct AnalyticsEventsClient {
queue: AnalyticsEventsQueue,
config: Arc<Config>,
analytics_enabled: Option<bool>,
}
impl AnalyticsEventsQueue {
pub(crate) fn new(auth_manager: Arc<AuthManager>) -> Self {
pub(crate) fn new(auth_manager: Arc<AuthManager>, base_url: String) -> Self {
let (sender, mut receiver) = mpsc::channel(ANALYTICS_EVENTS_QUEUE_SIZE);
tokio::spawn(async move {
while let Some(job) = receiver.recv().await {
match job {
TrackEventsJob::SkillInvocations(job) => {
send_track_skill_invocations(&auth_manager, job).await;
send_track_skill_invocations(&auth_manager, &base_url, job).await;
}
TrackEventsJob::AppMentioned(job) => {
send_track_app_mentioned(&auth_manager, job).await;
send_track_app_mentioned(&auth_manager, &base_url, job).await;
}
TrackEventsJob::AppUsed(job) => {
send_track_app_used(&auth_manager, job).await;
send_track_app_used(&auth_manager, &base_url, job).await;
}
TrackEventsJob::PluginUsed(job) => {
send_track_plugin_used(&auth_manager, job).await;
send_track_plugin_used(&auth_manager, &base_url, job).await;
}
TrackEventsJob::PluginInstalled(job) => {
send_track_plugin_installed(&auth_manager, job).await;
send_track_plugin_installed(&auth_manager, &base_url, job).await;
}
TrackEventsJob::PluginUninstalled(job) => {
send_track_plugin_uninstalled(&auth_manager, job).await;
send_track_plugin_uninstalled(&auth_manager, &base_url, job).await;
}
TrackEventsJob::PluginEnabled(job) => {
send_track_plugin_enabled(&auth_manager, job).await;
send_track_plugin_enabled(&auth_manager, &base_url, job).await;
}
TrackEventsJob::PluginDisabled(job) => {
send_track_plugin_disabled(&auth_manager, job).await;
send_track_plugin_disabled(&auth_manager, &base_url, job).await;
}
}
}
@@ -147,60 +147,51 @@ impl AnalyticsEventsQueue {
}
impl AnalyticsEventsClient {
pub fn new(config: Arc<Config>, auth_manager: Arc<AuthManager>) -> Self {
pub fn new(
auth_manager: Arc<AuthManager>,
base_url: String,
analytics_enabled: Option<bool>,
) -> Self {
Self {
queue: AnalyticsEventsQueue::new(Arc::clone(&auth_manager)),
config,
queue: AnalyticsEventsQueue::new(Arc::clone(&auth_manager), base_url),
analytics_enabled,
}
}
pub(crate) fn track_skill_invocations(
pub fn track_skill_invocations(
&self,
tracking: TrackEventsContext,
invocations: Vec<SkillInvocation>,
) {
track_skill_invocations(
&self.queue,
Arc::clone(&self.config),
self.analytics_enabled,
Some(tracking),
invocations,
);
}
pub(crate) fn track_app_mentioned(
&self,
tracking: TrackEventsContext,
mentions: Vec<AppInvocation>,
) {
pub fn track_app_mentioned(&self, tracking: TrackEventsContext, mentions: Vec<AppInvocation>) {
track_app_mentioned(
&self.queue,
Arc::clone(&self.config),
self.analytics_enabled,
Some(tracking),
mentions,
);
}
pub(crate) fn track_app_used(&self, tracking: TrackEventsContext, app: AppInvocation) {
track_app_used(&self.queue, Arc::clone(&self.config), Some(tracking), app);
pub fn track_app_used(&self, tracking: TrackEventsContext, app: AppInvocation) {
track_app_used(&self.queue, self.analytics_enabled, Some(tracking), app);
}
pub(crate) fn track_plugin_used(
&self,
tracking: TrackEventsContext,
plugin: PluginTelemetryMetadata,
) {
track_plugin_used(
&self.queue,
Arc::clone(&self.config),
Some(tracking),
plugin,
);
pub fn track_plugin_used(&self, tracking: TrackEventsContext, plugin: PluginTelemetryMetadata) {
track_plugin_used(&self.queue, self.analytics_enabled, Some(tracking), plugin);
}
pub fn track_plugin_installed(&self, plugin: PluginTelemetryMetadata) {
track_plugin_management(
&self.queue,
Arc::clone(&self.config),
self.analytics_enabled,
PluginManagementEventType::Installed,
plugin,
);
@@ -209,7 +200,7 @@ impl AnalyticsEventsClient {
pub fn track_plugin_uninstalled(&self, plugin: PluginTelemetryMetadata) {
track_plugin_management(
&self.queue,
Arc::clone(&self.config),
self.analytics_enabled,
PluginManagementEventType::Uninstalled,
plugin,
);
@@ -218,7 +209,7 @@ impl AnalyticsEventsClient {
pub fn track_plugin_enabled(&self, plugin: PluginTelemetryMetadata) {
track_plugin_management(
&self.queue,
Arc::clone(&self.config),
self.analytics_enabled,
PluginManagementEventType::Enabled,
plugin,
);
@@ -227,7 +218,7 @@ impl AnalyticsEventsClient {
pub fn track_plugin_disabled(&self, plugin: PluginTelemetryMetadata) {
track_plugin_management(
&self.queue,
Arc::clone(&self.config),
self.analytics_enabled,
PluginManagementEventType::Disabled,
plugin,
);
@@ -246,31 +237,31 @@ enum TrackEventsJob {
}
struct TrackSkillInvocationsJob {
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: TrackEventsContext,
invocations: Vec<SkillInvocation>,
}
struct TrackAppMentionedJob {
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: TrackEventsContext,
mentions: Vec<AppInvocation>,
}
struct TrackAppUsedJob {
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: TrackEventsContext,
app: AppInvocation,
}
struct TrackPluginUsedJob {
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: TrackEventsContext,
plugin: PluginTelemetryMetadata,
}
struct TrackPluginManagementJob {
config: Arc<Config>,
analytics_enabled: Option<bool>,
plugin: PluginTelemetryMetadata,
}
@@ -379,11 +370,11 @@ struct CodexPluginUsedEventRequest {
pub(crate) fn track_skill_invocations(
queue: &AnalyticsEventsQueue,
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: Option<TrackEventsContext>,
invocations: Vec<SkillInvocation>,
) {
if config.analytics_enabled == Some(false) {
if analytics_enabled == Some(false) {
return;
}
let Some(tracking) = tracking else {
@@ -393,7 +384,7 @@ pub(crate) fn track_skill_invocations(
return;
}
let job = TrackEventsJob::SkillInvocations(TrackSkillInvocationsJob {
config,
analytics_enabled,
tracking,
invocations,
});
@@ -402,11 +393,11 @@ pub(crate) fn track_skill_invocations(
pub(crate) fn track_app_mentioned(
queue: &AnalyticsEventsQueue,
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: Option<TrackEventsContext>,
mentions: Vec<AppInvocation>,
) {
if config.analytics_enabled == Some(false) {
if analytics_enabled == Some(false) {
return;
}
let Some(tracking) = tracking else {
@@ -416,7 +407,7 @@ pub(crate) fn track_app_mentioned(
return;
}
let job = TrackEventsJob::AppMentioned(TrackAppMentionedJob {
config,
analytics_enabled,
tracking,
mentions,
});
@@ -425,11 +416,11 @@ pub(crate) fn track_app_mentioned(
pub(crate) fn track_app_used(
queue: &AnalyticsEventsQueue,
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: Option<TrackEventsContext>,
app: AppInvocation,
) {
if config.analytics_enabled == Some(false) {
if analytics_enabled == Some(false) {
return;
}
let Some(tracking) = tracking else {
@@ -439,7 +430,7 @@ pub(crate) fn track_app_used(
return;
}
let job = TrackEventsJob::AppUsed(TrackAppUsedJob {
config,
analytics_enabled,
tracking,
app,
});
@@ -448,11 +439,11 @@ pub(crate) fn track_app_used(
pub(crate) fn track_plugin_used(
queue: &AnalyticsEventsQueue,
config: Arc<Config>,
analytics_enabled: Option<bool>,
tracking: Option<TrackEventsContext>,
plugin: PluginTelemetryMetadata,
) {
if config.analytics_enabled == Some(false) {
if analytics_enabled == Some(false) {
return;
}
let Some(tracking) = tracking else {
@@ -462,7 +453,7 @@ pub(crate) fn track_plugin_used(
return;
}
let job = TrackEventsJob::PluginUsed(TrackPluginUsedJob {
config,
analytics_enabled,
tracking,
plugin,
});
@@ -471,14 +462,17 @@ pub(crate) fn track_plugin_used(
fn track_plugin_management(
queue: &AnalyticsEventsQueue,
config: Arc<Config>,
analytics_enabled: Option<bool>,
event_type: PluginManagementEventType,
plugin: PluginTelemetryMetadata,
) {
if config.analytics_enabled == Some(false) {
if analytics_enabled == Some(false) {
return;
}
let job = TrackPluginManagementJob { config, plugin };
let job = TrackPluginManagementJob {
analytics_enabled,
plugin,
};
let job = match event_type {
PluginManagementEventType::Installed => TrackEventsJob::PluginInstalled(job),
PluginManagementEventType::Uninstalled => TrackEventsJob::PluginUninstalled(job),
@@ -488,9 +482,13 @@ fn track_plugin_management(
queue.try_send(job);
}
async fn send_track_skill_invocations(auth_manager: &AuthManager, job: TrackSkillInvocationsJob) {
async fn send_track_skill_invocations(
auth_manager: &AuthManager,
base_url: &str,
job: TrackSkillInvocationsJob,
) {
let TrackSkillInvocationsJob {
config,
analytics_enabled,
tracking,
invocations,
} = job;
@@ -525,7 +523,7 @@ async fn send_track_skill_invocations(auth_manager: &AuthManager, job: TrackSkil
thread_id: Some(tracking.thread_id.clone()),
invoke_type: Some(invocation.invocation_type),
model_slug: Some(tracking.model_slug.clone()),
product_client_id: Some(crate::default_client::originator().value),
product_client_id: Some(originator().value),
repo_url,
skill_scope: Some(skill_scope.to_string()),
},
@@ -533,12 +531,16 @@ async fn send_track_skill_invocations(auth_manager: &AuthManager, job: TrackSkil
));
}
send_track_events(auth_manager, config, events).await;
send_track_events(auth_manager, analytics_enabled, base_url, events).await;
}
async fn send_track_app_mentioned(auth_manager: &AuthManager, job: TrackAppMentionedJob) {
async fn send_track_app_mentioned(
auth_manager: &AuthManager,
base_url: &str,
job: TrackAppMentionedJob,
) {
let TrackAppMentionedJob {
config,
analytics_enabled,
tracking,
mentions,
} = job;
@@ -553,12 +555,12 @@ async fn send_track_app_mentioned(auth_manager: &AuthManager, job: TrackAppMenti
})
.collect::<Vec<_>>();
send_track_events(auth_manager, config, events).await;
send_track_events(auth_manager, analytics_enabled, base_url, events).await;
}
async fn send_track_app_used(auth_manager: &AuthManager, job: TrackAppUsedJob) {
async fn send_track_app_used(auth_manager: &AuthManager, base_url: &str, job: TrackAppUsedJob) {
let TrackAppUsedJob {
config,
analytics_enabled,
tracking,
app,
} = job;
@@ -568,12 +570,16 @@ async fn send_track_app_used(auth_manager: &AuthManager, job: TrackAppUsedJob) {
event_params,
})];
send_track_events(auth_manager, config, events).await;
send_track_events(auth_manager, analytics_enabled, base_url, events).await;
}
async fn send_track_plugin_used(auth_manager: &AuthManager, job: TrackPluginUsedJob) {
async fn send_track_plugin_used(
auth_manager: &AuthManager,
base_url: &str,
job: TrackPluginUsedJob,
) {
let TrackPluginUsedJob {
config,
analytics_enabled,
tracking,
plugin,
} = job;
@@ -582,31 +588,52 @@ async fn send_track_plugin_used(auth_manager: &AuthManager, job: TrackPluginUsed
event_params: codex_plugin_used_metadata(&tracking, plugin),
})];
send_track_events(auth_manager, config, events).await;
send_track_events(auth_manager, analytics_enabled, base_url, events).await;
}
async fn send_track_plugin_installed(auth_manager: &AuthManager, job: TrackPluginManagementJob) {
send_track_plugin_management_event(auth_manager, job, "codex_plugin_installed").await;
async fn send_track_plugin_installed(
auth_manager: &AuthManager,
base_url: &str,
job: TrackPluginManagementJob,
) {
send_track_plugin_management_event(auth_manager, base_url, job, "codex_plugin_installed").await;
}
async fn send_track_plugin_uninstalled(auth_manager: &AuthManager, job: TrackPluginManagementJob) {
send_track_plugin_management_event(auth_manager, job, "codex_plugin_uninstalled").await;
async fn send_track_plugin_uninstalled(
auth_manager: &AuthManager,
base_url: &str,
job: TrackPluginManagementJob,
) {
send_track_plugin_management_event(auth_manager, base_url, job, "codex_plugin_uninstalled")
.await;
}
async fn send_track_plugin_enabled(auth_manager: &AuthManager, job: TrackPluginManagementJob) {
send_track_plugin_management_event(auth_manager, job, "codex_plugin_enabled").await;
async fn send_track_plugin_enabled(
auth_manager: &AuthManager,
base_url: &str,
job: TrackPluginManagementJob,
) {
send_track_plugin_management_event(auth_manager, base_url, job, "codex_plugin_enabled").await;
}
async fn send_track_plugin_disabled(auth_manager: &AuthManager, job: TrackPluginManagementJob) {
send_track_plugin_management_event(auth_manager, job, "codex_plugin_disabled").await;
async fn send_track_plugin_disabled(
auth_manager: &AuthManager,
base_url: &str,
job: TrackPluginManagementJob,
) {
send_track_plugin_management_event(auth_manager, base_url, job, "codex_plugin_disabled").await;
}
async fn send_track_plugin_management_event(
auth_manager: &AuthManager,
base_url: &str,
job: TrackPluginManagementJob,
event_type: &'static str,
) {
let TrackPluginManagementJob { config, plugin } = job;
let TrackPluginManagementJob {
analytics_enabled,
plugin,
} = job;
let event_params = codex_plugin_metadata(plugin);
let event = CodexPluginEventRequest {
event_type,
@@ -620,7 +647,7 @@ async fn send_track_plugin_management_event(
_ => unreachable!("unknown plugin management event type"),
}];
send_track_events(auth_manager, config, events).await;
send_track_events(auth_manager, analytics_enabled, base_url, events).await;
}
fn codex_app_metadata(tracking: &TrackEventsContext, app: AppInvocation) -> CodexAppMetadata {
@@ -629,7 +656,7 @@ fn codex_app_metadata(tracking: &TrackEventsContext, app: AppInvocation) -> Code
thread_id: Some(tracking.thread_id.clone()),
turn_id: Some(tracking.turn_id.clone()),
app_name: app.app_name,
product_client_id: Some(crate::default_client::originator().value),
product_client_id: Some(originator().value),
invoke_type: app.invocation_type,
model_slug: Some(tracking.model_slug.clone()),
}
@@ -654,7 +681,7 @@ fn codex_plugin_metadata(plugin: PluginTelemetryMetadata) -> CodexPluginMetadata
.map(|connector_id| connector_id.0)
.collect()
}),
product_client_id: Some(crate::default_client::originator().value),
product_client_id: Some(originator().value),
}
}
@@ -672,9 +699,13 @@ fn codex_plugin_used_metadata(
async fn send_track_events(
auth_manager: &AuthManager,
config: Arc<Config>,
analytics_enabled: Option<bool>,
base_url: &str,
events: Vec<TrackEventRequest>,
) {
if analytics_enabled == Some(false) {
return;
}
if events.is_empty() {
return;
}
@@ -692,7 +723,7 @@ async fn send_track_events(
return;
};
let base_url = config.chatgpt_base_url.trim_end_matches('/');
let base_url = base_url.trim_end_matches('/');
let url = format!("{base_url}/codex/analytics-events/events");
let payload = TrackEventsRequest { events };
@@ -11,10 +11,11 @@ use super::codex_app_metadata;
use super::codex_plugin_metadata;
use super::codex_plugin_used_metadata;
use super::normalize_path_for_skill_id;
use crate::plugins::AppConnectorId;
use crate::plugins::PluginCapabilitySummary;
use crate::plugins::PluginId;
use crate::plugins::PluginTelemetryMetadata;
use codex_login::default_client::originator;
use codex_plugin::AppConnectorId;
use codex_plugin::PluginCapabilitySummary;
use codex_plugin::PluginId;
use codex_plugin::PluginTelemetryMetadata;
use pretty_assertions::assert_eq;
use serde_json::json;
use std::collections::HashSet;
@@ -109,7 +110,7 @@ fn app_mentioned_event_serializes_expected_shape() {
"thread_id": "thread-1",
"turn_id": "turn-1",
"app_name": "Calendar",
"product_client_id": crate::default_client::originator().value,
"product_client_id": originator().value,
"invoke_type": "explicit",
"model_slug": "gpt-5"
}
@@ -147,7 +148,7 @@ fn app_used_event_serializes_expected_shape() {
"thread_id": "thread-2",
"turn_id": "turn-2",
"app_name": "Google Drive",
"product_client_id": crate::default_client::originator().value,
"product_client_id": originator().value,
"invoke_type": "implicit",
"model_slug": "gpt-5"
}
@@ -210,7 +211,7 @@ fn plugin_used_event_serializes_expected_shape() {
"has_skills": true,
"mcp_server_count": 2,
"connector_ids": ["calendar", "drive"],
"product_client_id": crate::default_client::originator().value,
"product_client_id": originator().value,
"thread_id": "thread-3",
"turn_id": "turn-3",
"model_slug": "gpt-5"
@@ -239,7 +240,7 @@ fn plugin_management_event_serializes_expected_shape() {
"has_skills": true,
"mcp_server_count": 2,
"connector_ids": ["calendar", "drive"],
"product_client_id": crate::default_client::originator().value
"product_client_id": originator().value
}
})
);
+8
View File
@@ -0,0 +1,8 @@
mod analytics_client;
pub use analytics_client::AnalyticsEventsClient;
pub use analytics_client::AppInvocation;
pub use analytics_client::InvocationType;
pub use analytics_client::SkillInvocation;
pub use analytics_client::TrackEventsContext;
pub use analytics_client::build_track_events_context;
+9 -4
View File
@@ -450,6 +450,8 @@ fn config_write_error(code: ConfigWriteErrorCode, message: impl Into<String>) ->
mod tests {
use super::*;
use codex_core::AnalyticsEventsClient;
use codex_core::AuthManager;
use codex_core::CodexAuth;
use codex_core::config_loader::NetworkRequirementsToml as CoreNetworkRequirementsToml;
use codex_features::Feature;
use codex_protocol::protocol::AskForApproval as CoreAskForApproval;
@@ -651,6 +653,7 @@ mod tests {
.await
.expect("load analytics config"),
);
let auth_manager = AuthManager::from_auth_for_testing(CodexAuth::from_api_key("test"));
let config_api = ConfigApi::new(
codex_home.path().to_path_buf(),
Arc::new(RwLock::new(Vec::new())),
@@ -659,10 +662,12 @@ mod tests {
Arc::new(RwLock::new(CloudRequirementsLoader::default())),
reloader.clone(),
AnalyticsEventsClient::new(
analytics_config,
codex_core::test_support::auth_manager_from_auth(
codex_core::CodexAuth::from_api_key("test"),
),
auth_manager,
analytics_config
.chatgpt_base_url
.trim_end_matches('/')
.to_string(),
analytics_config.analytics_enabled,
),
);
+5 -2
View File
@@ -222,8 +222,11 @@ impl MessageProcessor {
auth_manager.set_external_auth_refresher(Arc::new(ExternalAuthRefreshBridge {
outgoing: outgoing.clone(),
}));
let analytics_events_client =
AnalyticsEventsClient::new(Arc::clone(&config), Arc::clone(&auth_manager));
let analytics_events_client = AnalyticsEventsClient::new(
Arc::clone(&auth_manager),
config.chatgpt_base_url.trim_end_matches('/').to_string(),
config.analytics_enabled,
);
thread_manager
.plugins_manager()
.set_analytics_events_client(analytics_events_client.clone());
+1
View File
@@ -27,6 +27,7 @@ bm25 = { workspace = true }
chardetng = { workspace = true }
chrono = { workspace = true, features = ["serde"] }
clap = { workspace = true, features = ["derive"] }
codex-analytics = { workspace = true }
codex-api = { workspace = true }
codex-app-server-protocol = { workspace = true }
codex-apply-patch = { workspace = true }
+6 -5
View File
@@ -12,10 +12,6 @@ use crate::SandboxState;
use crate::agent::AgentControl;
use crate::agent::AgentStatus;
use crate::agent::agent_status_from_event;
use crate::analytics_client::AnalyticsEventsClient;
use crate::analytics_client::AppInvocation;
use crate::analytics_client::InvocationType;
use crate::analytics_client::build_track_events_context;
use crate::apps::render_apps_section;
use crate::auth_env_telemetry::collect_auth_env_telemetry;
use crate::commit_attribution::commit_message_trailer_instruction;
@@ -349,6 +345,10 @@ use crate::turn_timing::record_turn_ttft_metric;
use crate::unified_exec::UnifiedExecProcessManager;
use crate::util::backoff;
use crate::windows_sandbox::WindowsSandboxLevelExt;
use codex_analytics::AnalyticsEventsClient;
use codex_analytics::AppInvocation;
use codex_analytics::InvocationType;
use codex_analytics::build_track_events_context;
use codex_async_utils::OrCancelExt;
use codex_git_utils::get_git_repo_root;
use codex_otel::SessionTelemetry;
@@ -1844,8 +1844,9 @@ impl Session {
shell_zsh_path: config.zsh_path.clone(),
main_execve_wrapper_exe: config.main_execve_wrapper_exe.clone(),
analytics_events_client: AnalyticsEventsClient::new(
Arc::clone(&config),
Arc::clone(&auth_manager),
config.chatgpt_base_url.trim_end_matches('/').to_string(),
config.analytics_enabled,
),
hooks,
rollout: Mutex::new(rollout_recorder),
+4 -2
View File
@@ -2668,8 +2668,9 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
shell_zsh_path: None,
main_execve_wrapper_exe: config.main_execve_wrapper_exe.clone(),
analytics_events_client: AnalyticsEventsClient::new(
Arc::clone(&config),
Arc::clone(&auth_manager),
config.chatgpt_base_url.trim_end_matches('/').to_string(),
config.analytics_enabled,
),
hooks: Hooks::new(HooksConfig {
legacy_notify_argv: config.notify.clone(),
@@ -3503,8 +3504,9 @@ pub(crate) async fn make_session_and_context_with_dynamic_tools_and_rx(
shell_zsh_path: None,
main_execve_wrapper_exe: config.main_execve_wrapper_exe.clone(),
analytics_events_client: AnalyticsEventsClient::new(
Arc::clone(&config),
Arc::clone(&auth_manager),
config.chatgpt_base_url.trim_end_matches('/').to_string(),
config.analytics_enabled,
),
hooks: Hooks::new(HooksConfig {
legacy_notify_argv: config.notify.clone(),
+1 -2
View File
@@ -5,7 +5,6 @@
// the TUI or the tracing stack).
#![deny(clippy::print_stdout, clippy::print_stderr)]
mod analytics_client;
pub mod api_bridge;
mod apply_patch;
mod apps;
@@ -108,9 +107,9 @@ pub type NewConversation = NewThread;
#[deprecated(note = "use CodexThread")]
pub type CodexConversation = CodexThread;
// Re-export common auth types for workspace consumers
pub use analytics_client::AnalyticsEventsClient;
pub use auth::AuthManager;
pub use auth::CodexAuth;
pub use codex_analytics::AnalyticsEventsClient;
mod default_client_forwarding;
/// Default Codex HTTP client headers and reqwest construction.
+3 -3
View File
@@ -8,9 +8,6 @@ use codex_app_server_protocol::McpServerElicitationRequest;
use codex_app_server_protocol::McpServerElicitationRequestParams;
use tracing::error;
use crate::analytics_client::AppInvocation;
use crate::analytics_client::InvocationType;
use crate::analytics_client::build_track_events_context;
use crate::arc_monitor::ArcMonitorOutcome;
use crate::arc_monitor::monitor_action;
use crate::codex::Session;
@@ -32,6 +29,9 @@ use crate::protocol::McpInvocation;
use crate::protocol::McpToolCallBeginEvent;
use crate::protocol::McpToolCallEndEvent;
use crate::state_db;
use codex_analytics::AppInvocation;
use codex_analytics::InvocationType;
use codex_analytics::build_track_events_context;
use codex_features::Feature;
use codex_protocol::mcp::CallToolResult;
use codex_protocol::openai_models::InputModality;
+4 -4
View File
@@ -2,14 +2,14 @@ use std::collections::HashMap;
use std::collections::HashSet;
use std::path::PathBuf;
use crate::analytics_client::AnalyticsEventsClient;
use crate::analytics_client::InvocationType;
use crate::analytics_client::SkillInvocation;
use crate::analytics_client::TrackEventsContext;
use crate::instructions::SkillInstructions;
use crate::mention_syntax::TOOL_MENTION_SIGIL;
use crate::mentions::build_skill_name_counts;
use crate::skills::SkillMetadata;
use codex_analytics::AnalyticsEventsClient;
use codex_analytics::InvocationType;
use codex_analytics::SkillInvocation;
use codex_analytics::TrackEventsContext;
use codex_otel::SessionTelemetry;
use codex_protocol::models::ResponseItem;
use codex_protocol::user_input::UserInput;
+3 -3
View File
@@ -2,13 +2,13 @@ use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;
use crate::analytics_client::InvocationType;
use crate::analytics_client::SkillInvocation;
use crate::analytics_client::build_track_events_context;
use crate::codex::Session;
use crate::codex::TurnContext;
use crate::skills::SkillLoadOutcome;
use crate::skills::SkillMetadata;
use codex_analytics::InvocationType;
use codex_analytics::SkillInvocation;
use codex_analytics::build_track_events_context;
pub(crate) fn build_implicit_skill_path_indexes(
skills: Vec<SkillMetadata>,
+1 -1
View File
@@ -4,7 +4,6 @@ use std::sync::Arc;
use crate::AuthManager;
use crate::RolloutRecorder;
use crate::agent::AgentControl;
use crate::analytics_client::AnalyticsEventsClient;
use crate::client::ModelClient;
use crate::config::StartedNetworkProxy;
use crate::exec_policy::ExecPolicyManager;
@@ -20,6 +19,7 @@ use crate::tools::network_approval::NetworkApprovalService;
use crate::tools::runtimes::ExecveSessionApproval;
use crate::tools::sandboxing::ApprovalStore;
use crate::unified_exec::UnifiedExecProcessManager;
use codex_analytics::AnalyticsEventsClient;
use codex_exec_server::Environment;
use codex_hooks::Hooks;
use codex_otel::SessionTelemetry;