diff --git a/codex-rs/analytics/src/analytics_client_tests.rs b/codex-rs/analytics/src/analytics_client_tests.rs index 6f040600d1..d8c55a3c04 100644 --- a/codex-rs/analytics/src/analytics_client_tests.rs +++ b/codex-rs/analytics/src/analytics_client_tests.rs @@ -860,6 +860,7 @@ fn plugin_measurements(rows: Vec) -> PluginMeasurementsInp thread_id: "thread-1".to_string(), turn_id: "turn-1".to_string(), item_id: "item-1".to_string(), + originator: "codex_cli_rs".to_string(), plugin_id: "sample@openai-curated".to_string(), execution_id: "execution-1".to_string(), operation: "security_scan".to_string(), @@ -2796,6 +2797,7 @@ async fn plugin_measurement_batch_emits_directly_and_filters_invalid_rows() { "execution_id": "execution-1", "operation": "security_scan", "measurement_name": "finding_count", + "originator": "codex_cli_rs", "number_value": 3.0, "dimensions": {"severity": "high"}, }, @@ -2810,6 +2812,7 @@ async fn plugin_measurement_batch_emits_directly_and_filters_invalid_rows() { "execution_id": "execution-1", "operation": "security_scan", "measurement_name": "files_scanned", + "originator": "codex_cli_rs", "number_value": 17.0, "dimensions": null, }, diff --git a/codex-rs/analytics/src/client_tests.rs b/codex-rs/analytics/src/client_tests.rs index b6da8cfb9f..0529e0878d 100644 --- a/codex-rs/analytics/src/client_tests.rs +++ b/codex-rs/analytics/src/client_tests.rs @@ -424,6 +424,7 @@ async fn api_key_auth_sends_only_plugin_events_to_codex_backend() { thread_id: thread_id.to_string(), turn_id: "turn-1".to_string(), item_id: "item-1".to_string(), + originator: "codex_cli_rs".to_string(), plugin_id: plugin_id.to_string(), execution_id: "execution-1".to_string(), operation: "security_scan".to_string(), @@ -706,6 +707,7 @@ fn track_plugin_measurements_rejects_unbounded_inputs_before_queueing() { thread_id: "thread-1".to_string(), turn_id: "turn-1".to_string(), item_id: "item-1".to_string(), + originator: "codex_cli_rs".to_string(), plugin_id: "sample@openai-curated".to_string(), execution_id: "execution-1".to_string(), operation: "security_scan".to_string(), diff --git a/codex-rs/analytics/src/events.rs b/codex-rs/analytics/src/events.rs index a984f2791f..613d1eb0ab 100644 --- a/codex-rs/analytics/src/events.rs +++ b/codex-rs/analytics/src/events.rs @@ -778,6 +778,7 @@ pub(crate) struct CodexPluginMeasurementEventParams { pub(crate) thread_id: String, pub(crate) turn_id: String, pub(crate) item_id: String, + pub(crate) originator: String, pub(crate) plugin_id: String, pub(crate) execution_id: String, pub(crate) operation: String, diff --git a/codex-rs/analytics/src/facts.rs b/codex-rs/analytics/src/facts.rs index 393429aa54..b4e431b998 100644 --- a/codex-rs/analytics/src/facts.rs +++ b/codex-rs/analytics/src/facts.rs @@ -604,6 +604,7 @@ pub struct PluginMeasurementsInput { pub thread_id: String, pub turn_id: String, pub item_id: String, + pub originator: String, pub plugin_id: String, pub execution_id: String, pub operation: String, diff --git a/codex-rs/analytics/src/reducer.rs b/codex-rs/analytics/src/reducer.rs index 0378f2b19c..93b3b2dca8 100644 --- a/codex-rs/analytics/src/reducer.rs +++ b/codex-rs/analytics/src/reducer.rs @@ -2055,6 +2055,7 @@ impl AnalyticsReducer { thread_id, turn_id, item_id, + originator, plugin_id, execution_id, operation, @@ -2070,6 +2071,7 @@ impl AnalyticsReducer { thread_id: thread_id.clone(), turn_id: turn_id.clone(), item_id: item_id.clone(), + originator: originator.clone(), plugin_id: plugin_id.clone(), execution_id: execution_id.clone(), operation: operation.clone(), diff --git a/codex-rs/app-server/tests/suite/v2/analytics.rs b/codex-rs/app-server/tests/suite/v2/analytics.rs index 6ab5ee10b2..142baeaa37 100644 --- a/codex-rs/app-server/tests/suite/v2/analytics.rs +++ b/codex-rs/app-server/tests/suite/v2/analytics.rs @@ -788,6 +788,7 @@ enabled = true let thread_request = mcp .send_thread_start_request_with_auto_env(ThreadStartParams { model: Some("mock-model".to_string()), + service_name: Some("codex_work_desktop".to_string()), ..Default::default() }) .await?; @@ -953,6 +954,7 @@ enabled = true "measurement_name", "number_value", "operation", + "originator", "plugin_id", "thread_id", "turn_id", @@ -960,6 +962,7 @@ enabled = true ); assert_eq!(event_params["thread_id"], thread_id); assert_eq!(event_params["turn_id"], turn_id); + assert_eq!(event_params["originator"], "codex_work_desktop"); } Ok(()) diff --git a/codex-rs/core/src/plugins/metrics.rs b/codex-rs/core/src/plugins/metrics.rs index 5e81763249..ccea42e67e 100644 --- a/codex-rs/core/src/plugins/metrics.rs +++ b/codex-rs/core/src/plugins/metrics.rs @@ -49,6 +49,7 @@ pub(crate) async fn finish_and_track_measurements( thread_id: session.thread_id().to_string(), turn_id: turn.sub_id.clone(), item_id: item_id.to_string(), + originator: turn.originator.clone(), plugin_id: batch.plugin_id, execution_id: batch.execution_id, operation: batch.operation,