diff --git a/codex-rs/analytics/src/analytics_client.rs b/codex-rs/analytics/src/analytics_client.rs index 646b4fc6ac..a83aa13ab0 100644 --- a/codex-rs/analytics/src/analytics_client.rs +++ b/codex-rs/analytics/src/analytics_client.rs @@ -735,13 +735,6 @@ fn personality_mode(personality: Option) -> Option { Some(personality) => Some(personality.to_string()), } } - -fn codex_thread_initialized_event_params( - thread_event: CodexThreadInitializedEvent, -) -> CodexThreadInitializedEventParams { - codex_thread_initialized_event_params_with_product_client_id(originator().value, thread_event) -} - fn codex_thread_initialized_event_request( product_client_id: String, thread_event: CodexThreadInitializedEvent, diff --git a/codex-rs/analytics/src/analytics_client_tests.rs b/codex-rs/analytics/src/analytics_client_tests.rs index 8d59236c31..86e3973f33 100644 --- a/codex-rs/analytics/src/analytics_client_tests.rs +++ b/codex-rs/analytics/src/analytics_client_tests.rs @@ -264,6 +264,7 @@ fn turn_event_serializes_expected_shape() { #[test] fn thread_initialized_event_serializes_expected_shape() { let event = TrackEventRequest::ThreadInitialized(codex_thread_initialized_event_request( + originator().value, CodexThreadInitializedEvent { thread_id: "thread-0".to_string(), model: "gpt-5".to_string(), @@ -300,6 +301,7 @@ fn thread_initialized_event_serializes_expected_shape() { #[test] fn thread_initialized_event_serializes_subagent_source() { let event = TrackEventRequest::ThreadInitialized(codex_thread_initialized_event_request( + originator().value, CodexThreadInitializedEvent { thread_id: "thread-1".to_string(), model: "gpt-5".to_string(), @@ -321,6 +323,7 @@ fn thread_initialized_event_serializes_subagent_source() { #[test] fn thread_initialized_event_omits_non_user_non_subagent_session_source() { let event = TrackEventRequest::ThreadInitialized(codex_thread_initialized_event_request( + originator().value, CodexThreadInitializedEvent { thread_id: "thread-2".to_string(), model: "gpt-5".to_string(), diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index f824877c5b..74809e182d 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -186,30 +186,30 @@ async fn user_turn_tracks_turn_metadata_analytics() -> anyhow::Result<()> { wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; let deadline = Instant::now() + Duration::from_secs(10); - let analytics_request = loop { + let event = loop { let requests = server.received_requests().await.unwrap_or_default(); - if let Some(request) = requests + let turn_events = requests .into_iter() - .find(|request| request.url.path() == "/codex/analytics-events/events") - { - break request; + .filter(|request| request.url.path() == "/codex/analytics-events/events") + .filter_map(|request| serde_json::from_slice::(&request.body).ok()) + .flat_map(|payload| { + payload["events"] + .as_array() + .cloned() + .unwrap_or_default() + .into_iter() + }) + .filter(|event| event["event_type"] == "codex_turn_event") + .collect::>(); + if let Some(event) = turn_events.last().cloned() { + break event; } if Instant::now() >= deadline { - panic!("timed out waiting for turn analytics request"); + panic!("timed out waiting for turn analytics event"); } tokio::time::sleep(Duration::from_millis(50)).await; }; - let payload: Value = serde_json::from_slice(&analytics_request.body)?; - let event = payload["events"] - .as_array() - .and_then(|events| { - events - .iter() - .find(|event| event["event_type"] == "codex_turn_event") - }) - .expect("codex_turn_event should be present"); - let event_params = &event["event_params"]; assert_eq!(event_params["sandbox_policy"], "read_only");