diff --git a/codex-rs/core/src/analytics_client.rs b/codex-rs/core/src/analytics_client.rs index 71ce395d57..d25f4a075d 100644 --- a/codex-rs/core/src/analytics_client.rs +++ b/codex-rs/core/src/analytics_client.rs @@ -420,23 +420,38 @@ struct CodexAppUsedEventRequest { event_params: CodexAppMetadata, } -#[derive(Serialize)] +#[derive(Default, Serialize)] struct CodexTurnEventParams { + #[serde(skip_serializing_if = "Option::is_none")] thread_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] turn_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] product_client_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] model_slug: Option, + #[serde(skip_serializing_if = "Option::is_none")] submission_type: Option, + #[serde(skip_serializing_if = "Option::is_none")] model_provider: Option, sandbox_policy: Option<&'static str>, + #[serde(skip_serializing_if = "Option::is_none")] reasoning_effort: Option, + #[serde(skip_serializing_if = "Option::is_none")] reasoning_summary: Option, + #[serde(skip_serializing_if = "Option::is_none")] service_tier: Option, + #[serde(skip_serializing_if = "Option::is_none")] approval_policy: Option, + #[serde(skip_serializing_if = "Option::is_none")] approvals_reviewer: Option, + #[serde(skip_serializing_if = "Option::is_none")] sandbox_network_access: Option, + #[serde(skip_serializing_if = "Option::is_none")] collaboration_mode: Option<&'static str>, + #[serde(skip_serializing_if = "Option::is_none")] personality: Option, + #[serde(skip_serializing_if = "Option::is_none")] num_input_images: Option, } @@ -842,18 +857,7 @@ fn codex_turn_steer_event_params( turn_id: Some(tracking.turn_id.clone()), product_client_id: Some(crate::default_client::originator().value), model_slug: Some(tracking.model_slug.clone()), - submission_type: None, - model_provider: None, - sandbox_policy: None, - reasoning_effort: None, - reasoning_summary: None, - service_tier: None, - approval_policy: None, - approvals_reviewer: None, - sandbox_network_access: None, - collaboration_mode: None, - personality: None, - num_input_images: None, + ..Default::default() } } diff --git a/codex-rs/core/src/analytics_client_tests.rs b/codex-rs/core/src/analytics_client_tests.rs index a3052a36b4..6b0f550c9f 100644 --- a/codex-rs/core/src/analytics_client_tests.rs +++ b/codex-rs/core/src/analytics_client_tests.rs @@ -277,18 +277,7 @@ fn turn_steer_event_serializes_expected_shape() { "thread_id": "thread-2", "turn_id": "turn-2", "product_client_id": crate::default_client::originator().value, - "model_slug": "gpt-5", - "submission_type": null, - "sandbox_policy": null, - "reasoning_effort": null, - "reasoning_summary": null, - "service_tier": null, - "approval_policy": null, - "approvals_reviewer": null, - "sandbox_network_access": null, - "collaboration_mode": null, - "personality": null, - "num_input_images": null + "model_slug": "gpt-5" } }) ); diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index 512e15f1d0..8f91366fee 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -443,13 +443,18 @@ async fn user_turn_tracks_turn_steer_analytics() -> anyhow::Result<()> { wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; let event = wait_for_analytics_event(&server, "codex_turn_event", |event| { - event["event_params"]["submission_type"].is_null() - && event["event_params"]["sandbox_policy"].is_null() + event["event_params"].get("submission_type").is_none() + && event["event_params"].get("sandbox_policy").is_none() }) .await; let event_params = &event["event_params"]; - assert!(event_params["submission_type"].is_null()); + assert!(event_params.get("submission_type").is_none()); + assert!(event_params.get("sandbox_policy").is_none()); + assert!(event_params.get("reasoning_effort").is_none()); + assert!(event_params.get("reasoning_summary").is_none()); + assert!(event_params.get("service_tier").is_none()); + assert!(event_params.get("collaboration_mode").is_none()); assert_eq!( event_params["product_client_id"], serde_json::json!(codex_core::default_client::originator().value) diff --git a/codex-rs/tui_app_server/src/chatwidget.rs b/codex-rs/tui_app_server/src/chatwidget.rs index 37277f4011..042459b409 100644 --- a/codex-rs/tui_app_server/src/chatwidget.rs +++ b/codex-rs/tui_app_server/src/chatwidget.rs @@ -2706,7 +2706,7 @@ impl ChatWidget { .map(|pending| pending.user_message) .collect(); if !pending_steers.is_empty() { - self.submit_user_message_with_type(merge_user_messages(pending_steers), None); + self.submit_user_message(merge_user_messages(pending_steers)); } else if let Some(combined) = self.drain_pending_messages_for_restore() { self.restore_user_message_to_composer(combined); }