Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions codex-rs/app-server-protocol/src/protocol/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,15 @@ pub struct ProfileV2 {
pub additional: HashMap<String, JsonValue>,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "snake_case")]
#[ts(export_to = "v2/")]
pub struct AnalyticsConfig {
pub enabled: Option<bool>,
#[serde(default, flatten)]
pub additional: HashMap<String, JsonValue>,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "snake_case")]
#[ts(export_to = "v2/")]
Expand All @@ -354,6 +363,7 @@ pub struct Config {
pub model_reasoning_effort: Option<ReasoningEffort>,
pub model_reasoning_summary: Option<ReasoningSummary>,
pub model_verbosity: Option<Verbosity>,
pub analytics: Option<AnalyticsConfig>,
#[serde(default, flatten)]
pub additional: HashMap<String, JsonValue>,
}
Expand Down
24 changes: 24 additions & 0 deletions codex-rs/core/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,10 @@ pub struct Config {
/// or placeholder replacement will occur for fast keypress bursts.
pub disable_paste_burst: bool,

/// When `false`, disables analytics across Codex product surfaces in this machine.
/// Defaults to `true`.
pub analytics: bool,

/// OTEL configuration (exporter type, endpoint, headers, etc.).
pub otel: crate::config::types::OtelConfig,
}
Expand Down Expand Up @@ -813,6 +817,10 @@ pub struct ConfigToml {
/// or placeholder replacement will occur for fast keypress bursts.
pub disable_paste_burst: Option<bool>,

/// When `false`, disables analytics across Codex product surfaces in this machine.
/// Defaults to `true`.
pub analytics: Option<crate::config::types::AnalyticsConfigToml>,

/// OTEL configuration.
pub otel: Option<crate::config::types::OtelConfigToml>,

Expand Down Expand Up @@ -1390,6 +1398,12 @@ impl Config {
notices: cfg.notice.unwrap_or_default(),
check_for_update_on_startup,
disable_paste_burst: cfg.disable_paste_burst.unwrap_or(false),
analytics: config_profile
.analytics
.as_ref()
.and_then(|a| a.enabled)
.or(cfg.analytics.as_ref().and_then(|a| a.enabled))
.unwrap_or(true),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this has been validated with legal right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I'll ping you in Slack with more details

tui_notifications: cfg
.tui
.as_ref()
Expand Down Expand Up @@ -3039,6 +3053,9 @@ approval_policy = "untrusted"
# `ConfigOverrides`.
profile = "gpt3"

[analytics]
enabled = true

[model_providers.openai-chat-completions]
name = "OpenAI using Chat Completions"
base_url = "https://api.openai.com/v1"
Expand All @@ -3064,6 +3081,9 @@ model = "o3"
model_provider = "openai"
approval_policy = "on-failure"

[profiles.zdr.analytics]
enabled = false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test to make sure this work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's there! see test_precedence_fixture_with_zdr_profile below, it checks that analytics is false


[profiles.gpt5]
model = "gpt-5.1"
model_provider = "openai"
Expand Down Expand Up @@ -3204,6 +3224,7 @@ model_verbosity = "high"
tui_notifications: Default::default(),
animations: true,
show_tooltips: true,
analytics: true,
tui_scroll_events_per_tick: None,
tui_scroll_wheel_lines: None,
tui_scroll_trackpad_lines: None,
Expand Down Expand Up @@ -3287,6 +3308,7 @@ model_verbosity = "high"
tui_notifications: Default::default(),
animations: true,
show_tooltips: true,
analytics: true,
tui_scroll_events_per_tick: None,
tui_scroll_wheel_lines: None,
tui_scroll_trackpad_lines: None,
Expand Down Expand Up @@ -3385,6 +3407,7 @@ model_verbosity = "high"
tui_notifications: Default::default(),
animations: true,
show_tooltips: true,
analytics: false,
tui_scroll_events_per_tick: None,
tui_scroll_wheel_lines: None,
tui_scroll_trackpad_lines: None,
Expand Down Expand Up @@ -3469,6 +3492,7 @@ model_verbosity = "high"
tui_notifications: Default::default(),
animations: true,
show_tooltips: true,
analytics: true,
tui_scroll_events_per_tick: None,
tui_scroll_wheel_lines: None,
tui_scroll_trackpad_lines: None,
Expand Down
1 change: 1 addition & 0 deletions codex-rs/core/src/config/profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct ConfigProfile {
pub experimental_use_freeform_apply_patch: Option<bool>,
pub tools_web_search: Option<bool>,
pub tools_view_image: Option<bool>,
pub analytics: Option<crate::config::types::AnalyticsConfigToml>,
/// Optional feature toggles scoped to this profile.
#[serde(default)]
pub features: Option<crate::features::FeaturesToml>,
Expand Down
9 changes: 9 additions & 0 deletions codex-rs/core/src/config/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,15 @@ pub enum HistoryPersistence {
None,
}

// ===== Analytics configuration =====

/// Analytics settings loaded from config.toml. Fields are optional so we can apply defaults.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
pub struct AnalyticsConfigToml {
/// When `false`, disables analytics across Codex product surfaces in this profile.
pub enabled: Option<bool>,
}

// ===== OTEL configuration =====

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
Expand Down
Loading