diff --git a/codex-rs/exec/src/lib.rs b/codex-rs/exec/src/lib.rs index 3e2cf21051..761625856e 100644 --- a/codex-rs/exec/src/lib.rs +++ b/codex-rs/exec/src/lib.rs @@ -40,6 +40,7 @@ use codex_app_server_protocol::ThreadReadResponse; use codex_app_server_protocol::ThreadResumeParams; use codex_app_server_protocol::ThreadResumeResponse; use codex_app_server_protocol::ThreadSortKey; +use codex_app_server_protocol::ThreadSource; use codex_app_server_protocol::ThreadSourceKind; use codex_app_server_protocol::ThreadStartParams; use codex_app_server_protocol::ThreadStartResponse; @@ -974,6 +975,7 @@ fn thread_start_params_from_config(config: &Config) -> ThreadStartParams { permissions, config: config_request_overrides_from_config(config), ephemeral: Some(config.ephemeral), + thread_source: Some(ThreadSource::User), ..ThreadStartParams::default() } } @@ -1082,6 +1084,7 @@ fn session_configured_from_thread_start_response( session_configured_from_thread_response( &response.thread.session_id, &response.thread.id, + response.thread.thread_source.map(Into::into), response.thread.name.clone(), response.thread.path.clone(), response.model.clone(), @@ -1103,6 +1106,7 @@ fn session_configured_from_thread_resume_response( session_configured_from_thread_response( &response.thread.session_id, &response.thread.id, + response.thread.thread_source.map(Into::into), response.thread.name.clone(), response.thread.path.clone(), response.model.clone(), @@ -1133,6 +1137,7 @@ fn review_target_to_api(target: ReviewTarget) -> ApiReviewTarget { fn session_configured_from_thread_response( session_id: &str, thread_id: &str, + thread_source: Option, thread_name: Option, rollout_path: Option, model: String, @@ -1154,7 +1159,7 @@ fn session_configured_from_thread_response( session_id, thread_id, forked_from_id: None, - thread_source: None, + thread_source, thread_name, model, model_provider_id, diff --git a/codex-rs/exec/src/lib_tests.rs b/codex-rs/exec/src/lib_tests.rs index 92dc0678e5..2f04b2d260 100644 --- a/codex-rs/exec/src/lib_tests.rs +++ b/codex-rs/exec/src/lib_tests.rs @@ -458,6 +458,25 @@ async fn thread_start_params_include_review_policy_when_auto_review_is_enabled() ); } +#[tokio::test] +async fn thread_start_params_include_user_thread_source() { + let codex_home = tempdir().expect("create temp codex home"); + let cwd = tempdir().expect("create temp cwd"); + let config = ConfigBuilder::default() + .codex_home(codex_home.path().to_path_buf()) + .fallback_cwd(Some(cwd.path().to_path_buf())) + .build() + .await + .expect("build config"); + + let params = thread_start_params_from_config(&config); + + assert_eq!( + params.thread_source, + Some(codex_app_server_protocol::ThreadSource::User) + ); +} + #[test] fn active_profile_selection_uses_profile_id_only() { let selection = permissions_selection_from_active_profile(ActivePermissionProfile::new( @@ -548,6 +567,27 @@ async fn session_configured_from_thread_response_uses_permission_profile_from_co ); } +#[tokio::test] +async fn session_configured_from_thread_response_preserves_thread_source() { + let codex_home = tempdir().expect("create temp codex home"); + let cwd = tempdir().expect("create temp cwd"); + let config = ConfigBuilder::default() + .codex_home(codex_home.path().to_path_buf()) + .fallback_cwd(Some(cwd.path().to_path_buf())) + .build() + .await + .expect("build config"); + let response = sample_thread_start_response(); + + let event = session_configured_from_thread_start_response(&response, &config) + .expect("build bootstrap session configured event"); + + assert_eq!( + event.thread_source, + Some(codex_protocol::protocol::ThreadSource::User) + ); +} + fn sample_thread_start_response() -> ThreadStartResponse { ThreadStartResponse { thread: codex_app_server_protocol::Thread { @@ -564,7 +604,7 @@ fn sample_thread_start_response() -> ThreadStartResponse { cwd: test_path_buf("/tmp").abs(), cli_version: "0.0.0".to_string(), source: codex_app_server_protocol::SessionSource::Cli, - thread_source: None, + thread_source: Some(codex_app_server_protocol::ThreadSource::User), agent_nickname: None, agent_role: None, git_info: None,