From 74b8b800c76e5c1b2deeb48a1d6b23e1a6d9b0ea Mon Sep 17 00:00:00 2001 From: Roy Han Date: Wed, 25 Mar 2026 09:59:56 -0700 Subject: [PATCH] session source update --- codex-rs/core/src/analytics_client.rs | 22 ++++------ codex-rs/core/src/analytics_client_tests.rs | 43 +++++++++++++++++--- codex-rs/core/tests/suite/thread_metadata.rs | 4 +- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/codex-rs/core/src/analytics_client.rs b/codex-rs/core/src/analytics_client.rs index a6b2d20fc2..de1a657dc8 100644 --- a/codex-rs/core/src/analytics_client.rs +++ b/codex-rs/core/src/analytics_client.rs @@ -49,7 +49,7 @@ pub(crate) struct CodexThreadStartedEvent { pub(crate) personality: Option, pub(crate) ephemeral: bool, pub(crate) session_source: SessionSource, - pub(crate) initial_history_type: InitialHistoryType, + pub(crate) initialization_mode: InitializationMode, pub(crate) subagent_source: Option, pub(crate) parent_thread_id: Option, pub(crate) created_at: u64, @@ -57,7 +57,7 @@ pub(crate) struct CodexThreadStartedEvent { #[derive(Clone, Copy, Debug, Serialize)] #[serde(rename_all = "snake_case")] -pub(crate) enum InitialHistoryType { +pub(crate) enum InitializationMode { New, Forked, Resumed, @@ -392,8 +392,8 @@ struct CodexThreadStartedEventParams { collaboration_mode: &'static str, personality: Option, ephemeral: bool, - session_source: String, - initial_history_type: InitialHistoryType, + session_source: Option<&'static str>, + initialization_mode: InitializationMode, subagent_source: Option, parent_thread_id: Option, created_at: u64, @@ -772,7 +772,7 @@ fn codex_thread_started_event_params( personality: thread_event.personality.map(|value| value.to_string()), ephemeral: thread_event.ephemeral, session_source: session_source_name(&thread_event.session_source), - initial_history_type: thread_event.initial_history_type, + initialization_mode: thread_event.initialization_mode, subagent_source: thread_event.subagent_source.map(subagent_source_name), parent_thread_id: thread_event.parent_thread_id, created_at: thread_event.created_at, @@ -832,15 +832,11 @@ fn collaboration_mode_mode(mode: ModeKind) -> &'static str { } } -fn session_source_name(session_source: &SessionSource) -> String { +fn session_source_name(session_source: &SessionSource) -> Option<&'static str> { match session_source { - SessionSource::Cli => "cli".to_string(), - SessionSource::VSCode => "vscode".to_string(), - SessionSource::Exec => "exec".to_string(), - SessionSource::Mcp => "mcp".to_string(), - SessionSource::Custom(source) => source.clone(), - SessionSource::SubAgent(_) => "subagent".to_string(), - SessionSource::Unknown => "unknown".to_string(), + SessionSource::Cli | SessionSource::VSCode | SessionSource::Exec => Some("user"), + SessionSource::SubAgent(_) => Some("subagent"), + SessionSource::Mcp | SessionSource::Custom(_) | SessionSource::Unknown => None, } } diff --git a/codex-rs/core/src/analytics_client_tests.rs b/codex-rs/core/src/analytics_client_tests.rs index 587f12a726..e738918852 100644 --- a/codex-rs/core/src/analytics_client_tests.rs +++ b/codex-rs/core/src/analytics_client_tests.rs @@ -6,7 +6,7 @@ use super::CodexPluginEventRequest; use super::CodexPluginUsedEventRequest; use super::CodexThreadStartedEvent; use super::CodexThreadStartedEventRequest; -use super::InitialHistoryType; +use super::InitializationMode; use super::InvocationType; use super::TrackEventRequest; use super::TrackEventsContext; @@ -218,7 +218,7 @@ fn thread_started_event_serializes_expected_shape() { personality: Some(Personality::Friendly), ephemeral: true, session_source: SessionSource::Exec, - initial_history_type: InitialHistoryType::New, + initialization_mode: InitializationMode::New, subagent_source: None, parent_thread_id: None, created_at: 1_716_000_000, @@ -246,8 +246,8 @@ fn thread_started_event_serializes_expected_shape() { "collaboration_mode": "plan", "personality": "friendly", "ephemeral": true, - "session_source": "exec", - "initial_history_type": "new", + "session_source": "user", + "initialization_mode": "new", "subagent_source": null, "parent_thread_id": null, "created_at": 1716000000 @@ -275,7 +275,7 @@ fn thread_started_event_serializes_subagent_source() { personality: None, ephemeral: false, session_source: SessionSource::SubAgent(SubAgentSource::Review), - initial_history_type: InitialHistoryType::New, + initialization_mode: InitializationMode::New, subagent_source: Some(SubAgentSource::Review), parent_thread_id: None, created_at: 1, @@ -287,6 +287,39 @@ fn thread_started_event_serializes_subagent_source() { assert_eq!(payload["event_params"]["subagent_source"], "review"); } +#[test] +fn thread_started_event_omits_non_user_non_subagent_session_source() { + let event = TrackEventRequest::ThreadStarted(CodexThreadStartedEventRequest { + event_type: "codex_thread_started", + event_params: codex_thread_started_event_params(CodexThreadStartedEvent { + thread_id: "thread-2".to_string(), + model: "gpt-5".to_string(), + model_provider: "openai".to_string(), + reasoning_effort: None, + reasoning_summary: None, + service_tier: None, + approval_policy: AskForApproval::OnRequest, + approvals_reviewer: ApprovalsReviewer::User, + sandbox_policy: SandboxPolicy::new_read_only_policy(), + sandbox_network_access: false, + collaboration_mode: ModeKind::Default, + personality: None, + ephemeral: false, + session_source: SessionSource::Mcp, + initialization_mode: InitializationMode::New, + subagent_source: None, + parent_thread_id: None, + created_at: 1, + }), + }); + + let payload = serde_json::to_value(&event).expect("serialize mcp thread started event"); + assert_eq!( + payload["event_params"]["session_source"], + serde_json::Value::Null + ); +} + #[test] fn plugin_used_event_serializes_expected_shape() { let tracking = TrackEventsContext { diff --git a/codex-rs/core/tests/suite/thread_metadata.rs b/codex-rs/core/tests/suite/thread_metadata.rs index 397039e7b2..1b46a5a457 100644 --- a/codex-rs/core/tests/suite/thread_metadata.rs +++ b/codex-rs/core/tests/suite/thread_metadata.rs @@ -81,8 +81,8 @@ async fn thread_start_tracks_thread_started_analytics() -> Result<()> { assert_eq!(event["event_params"]["collaboration_mode"], "default"); assert_eq!(event["event_params"]["personality"], "friendly"); assert_eq!(event["event_params"]["ephemeral"], true); - assert_eq!(event["event_params"]["session_source"], "exec"); - assert_eq!(event["event_params"]["initial_history_type"], "new"); + assert_eq!(event["event_params"]["session_source"], "user"); + assert_eq!(event["event_params"]["initialization_mode"], "new"); assert_eq!( event["event_params"]["subagent_source"], serde_json::Value::Null