diff --git a/codex-rs/core/src/agent/agent_resolver.rs b/codex-rs/core/src/agent/agent_resolver.rs index 115739c2f..fff2d7afd 100644 --- a/codex-rs/core/src/agent/agent_resolver.rs +++ b/codex-rs/core/src/agent/agent_resolver.rs @@ -18,7 +18,7 @@ pub(crate) async fn resolve_agent_target( session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, target) + .resolve_agent_reference(session.thread_id, &turn.session_source, target) .await .map_err(|err| match err { codex_protocol::error::CodexErr::UnsupportedOperation(message) => { @@ -32,5 +32,5 @@ fn register_session_root(session: &Arc, turn: &Arc) { session .services .agent_control - .register_session_root(session.conversation_id, turn.parent_thread_id); + .register_session_root(session.thread_id, turn.parent_thread_id); } diff --git a/codex-rs/core/src/codex_delegate.rs b/codex-rs/core/src/codex_delegate.rs index 678a6e5d1..5a1473b05 100644 --- a/codex-rs/core/src/codex_delegate.rs +++ b/codex-rs/core/src/codex_delegate.rs @@ -92,7 +92,7 @@ pub(crate) async fn run_codex_thread_interactive( conversation_history, session_source: SessionSource::SubAgent(subagent_source.clone()), forked_from_thread_id, - parent_thread_id: Some(parent_session.conversation_id), + parent_thread_id: Some(parent_session.thread_id), thread_source: Some(ThreadSource::Subagent), agent_control: parent_session.services.agent_control.clone(), dynamic_tools: Vec::new(), @@ -116,8 +116,8 @@ pub(crate) async fn run_codex_thread_interactive( &parent_session.services.analytics_events_client, client_metadata, codex.session.session_id(), - codex.session.conversation_id, - Some(parent_session.conversation_id), + codex.session.thread_id, + Some(parent_session.thread_id), thread_config, subagent_source, ); diff --git a/codex-rs/core/src/compact.rs b/codex-rs/core/src/compact.rs index a002ce20d..4ff35c09e 100644 --- a/codex-rs/core/src/compact.rs +++ b/codex-rs/core/src/compact.rs @@ -327,7 +327,7 @@ impl CompactionAnalyticsAttempt { ) -> Self { let active_context_tokens_before = sess.get_total_token_usage().await; Self { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: turn_context.sub_id.clone(), trigger, reason, diff --git a/codex-rs/core/src/goals.rs b/codex-rs/core/src/goals.rs index ca92f8bec..6e0663655 100644 --- a/codex-rs/core/src/goals.rs +++ b/codex-rs/core/src/goals.rs @@ -403,7 +403,7 @@ impl Session { let state_db = self.require_state_db_for_thread_goals().await?; state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await .map(|goal| goal.map(protocol_goal_from_state)) } @@ -442,14 +442,14 @@ impl Session { let goal = if let Some(objective) = objective.as_deref() { let existing_goal = state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await?; previous_status = existing_goal.as_ref().map(|goal| goal.status); if let Some(existing_goal) = existing_goal.as_ref() { state_db .thread_goals() .update_thread_goal( - self.conversation_id, + self.thread_id, codex_state::GoalUpdate { objective: Some(objective.to_string()), status: status.map(state_goal_status_from_protocol), @@ -461,7 +461,7 @@ impl Session { .ok_or_else(|| { anyhow::anyhow!( "cannot update goal for thread {}: no goal exists", - self.conversation_id + self.thread_id ) })? } else { @@ -469,7 +469,7 @@ impl Session { state_db .thread_goals() .replace_thread_goal( - self.conversation_id, + self.thread_id, objective, status .map(state_goal_status_from_protocol) @@ -481,7 +481,7 @@ impl Session { } else { let existing_goal = state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await?; previous_status = existing_goal.as_ref().map(|goal| goal.status); let expected_goal_id = existing_goal.map(|goal| goal.goal_id); @@ -489,7 +489,7 @@ impl Session { state_db .thread_goals() .update_thread_goal( - self.conversation_id, + self.thread_id, codex_state::GoalUpdate { objective: None, status, @@ -501,7 +501,7 @@ impl Session { .ok_or_else(|| { anyhow::anyhow!( "cannot update goal for thread {}: no goal exists", - self.conversation_id + self.thread_id ) })? }; @@ -509,7 +509,7 @@ impl Session { if objective.is_some() { set_thread_preview_from_goal_objective( &state_db, - self.conversation_id, + self.thread_id, goal.objective.as_str(), ) .await; @@ -546,7 +546,7 @@ impl Session { self.send_event( turn_context, EventMsg::ThreadGoalUpdated(ThreadGoalUpdatedEvent { - thread_id: self.conversation_id, + thread_id: self.thread_id, turn_id: Some(turn_context.sub_id.clone()), goal: goal.clone(), }), @@ -582,7 +582,7 @@ impl Session { let goal = state_db .thread_goals() .insert_thread_goal( - self.conversation_id, + self.thread_id, objective, codex_state::ThreadGoalStatus::Active, token_budget, @@ -591,16 +591,12 @@ impl Session { .ok_or_else(|| { anyhow::anyhow!( "cannot create a new goal because thread {} already has a goal", - self.conversation_id + self.thread_id ) })?; - set_thread_preview_from_goal_objective( - &state_db, - self.conversation_id, - goal.objective.as_str(), - ) - .await; + set_thread_preview_from_goal_objective(&state_db, self.thread_id, goal.objective.as_str()) + .await; let goal_id = goal.goal_id.clone(); self.emit_goal_created_metric(); let goal = protocol_goal_from_state(goal); @@ -617,7 +613,7 @@ impl Session { self.send_event( turn_context, EventMsg::ThreadGoalUpdated(ThreadGoalUpdatedEvent { - thread_id: self.conversation_id, + thread_id: self.thread_id, turn_id: Some(turn_context.sub_id.clone()), goal: goal.clone(), }), @@ -799,7 +795,7 @@ impl Session { ) -> anyhow::Result> { let goal = state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await?; Ok(goal.and_then(|goal| { expected_goal_id @@ -843,7 +839,7 @@ impl Session { }; match state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await { Ok(Some(goal)) @@ -981,7 +977,7 @@ impl Session { let outcome = state_db .thread_goals() .account_thread_goal_usage( - self.conversation_id, + self.thread_id, time_delta_seconds, token_delta, codex_state::GoalAccountingMode::ActiveOnly, @@ -1043,7 +1039,7 @@ impl Session { self.send_event( turn_context, EventMsg::ThreadGoalUpdated(ThreadGoalUpdatedEvent { - thread_id: self.conversation_id, + thread_id: self.thread_id, turn_id: Some(turn_context.sub_id.clone()), goal: goal.clone(), }), @@ -1106,7 +1102,7 @@ impl Session { match state_db .thread_goals() .account_thread_goal_usage( - self.conversation_id, + self.thread_id, time_delta_seconds, /*token_delta*/ 0, mode, @@ -1174,7 +1170,7 @@ impl Session { .await?; let Some(goal) = state_db .thread_goals() - .usage_limit_active_thread_goal(self.conversation_id) + .usage_limit_active_thread_goal(self.thread_id) .await? else { return Ok(()); @@ -1186,7 +1182,7 @@ impl Session { self.send_event( turn_context, EventMsg::ThreadGoalUpdated(ThreadGoalUpdatedEvent { - thread_id: self.conversation_id, + thread_id: self.thread_id, turn_id: Some(turn_context.sub_id.clone()), goal, }), @@ -1217,7 +1213,7 @@ impl Session { }; let Some(goal) = state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await? else { self.clear_stopped_thread_goal_runtime_state().await; @@ -1269,7 +1265,7 @@ impl Session { let goal_is_current = match self.state_db_for_thread_goals().await { Ok(Some(state_db)) => match state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await { Ok(Some(goal)) @@ -1367,7 +1363,7 @@ impl Session { }; let goal = match state_db .thread_goals() - .get_thread_goal(self.conversation_id) + .get_thread_goal(self.thread_id) .await { Ok(Some(goal)) => goal, @@ -1430,7 +1426,7 @@ impl Session { }; let thread_metadata_present = state_db - .get_thread(self.conversation_id) + .get_thread(self.thread_id) .await .context("failed to read thread metadata before reconciling thread goals")? .is_some(); @@ -1453,7 +1449,7 @@ impl Session { ) .await; let thread_metadata_present = state_db - .get_thread(self.conversation_id) + .get_thread(self.thread_id) .await .context("failed to read thread metadata after reconciling thread goals")? .is_some(); diff --git a/codex-rs/core/src/guardian/prompt.rs b/codex-rs/core/src/guardian/prompt.rs index 062a21dee..008e97957 100644 --- a/codex-rs/core/src/guardian/prompt.rs +++ b/codex-rs/core/src/guardian/prompt.rs @@ -186,7 +186,7 @@ pub(crate) async fn build_guardian_prompt_items_with_parent_turn( push_text(headings.transcript_end.to_string()); push_text(format!( "Reviewed Codex session id: {}\n", - session.conversation_id + session.thread_id )); if let Some(note) = omission_note { push_text(format!("\n{note}\n")); diff --git a/codex-rs/core/src/guardian/review.rs b/codex-rs/core/src/guardian/review.rs index 167b153e2..06d1a7893 100644 --- a/codex-rs/core/src/guardian/review.rs +++ b/codex-rs/core/src/guardian/review.rs @@ -265,7 +265,7 @@ async fn run_guardian_review( let action_summary = guardian_assessment_action(&request); let reviewed_action = guardian_reviewed_action(&request); let review_tracking = GuardianReviewTrackContext::new( - session.conversation_id.to_string(), + session.thread_id.to_string(), assessment_turn_id.clone(), review_id.clone(), target_item_id.clone(), diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index b8c5c9807..c139a910a 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -662,7 +662,7 @@ async fn run_review_on_session( None }; let mut analytics_result = GuardianReviewAnalyticsResult::from_session( - review_session.codex.session.conversation_id.to_string(), + review_session.codex.session.thread_id.to_string(), guardian_session_kind, params.model.clone(), guardian_reasoning_effort.map(|effort| effort.to_string()), diff --git a/codex-rs/core/src/guardian/tests.rs b/codex-rs/core/src/guardian/tests.rs index aba67d850..ffadd801c 100644 --- a/codex-rs/core/src/guardian/tests.rs +++ b/codex-rs/core/src/guardian/tests.rs @@ -176,7 +176,7 @@ async fn guardian_test_session_and_turn_with_base_url( base_url: &str, ) -> (Arc, Arc) { let (mut session, mut turn) = crate::session::tests::make_session_and_context().await; - session.conversation_id = fixed_guardian_parent_session_id(); + session.thread_id = fixed_guardian_parent_session_id(); let mut config = (*turn.config).clone(); config.model_provider.base_url = Some(format!("{base_url}/v1")); config.user_instructions = None; @@ -365,7 +365,7 @@ async fn build_guardian_prompt_full_mode_preserves_initial_review_format() -> an #[tokio::test(flavor = "current_thread")] async fn build_guardian_prompt_includes_parent_turn_denied_reads() -> anyhow::Result<()> { let (mut session, mut turn) = crate::session::tests::make_session_and_context().await; - session.conversation_id = fixed_guardian_parent_session_id(); + session.thread_id = fixed_guardian_parent_session_id(); let denied_root = test_path_buf("/repo/private").abs(); let denied_glob = test_path_buf("/repo/private/**").display().to_string(); turn.permission_profile = PermissionProfile::from_runtime_permissions( @@ -1415,7 +1415,7 @@ async fn guardian_review_request_layout_matches_model_visible_request_snapshot() .await; let (mut session, mut turn) = crate::session::tests::make_session_and_context().await; - session.conversation_id = fixed_guardian_parent_session_id(); + session.thread_id = fixed_guardian_parent_session_id(); let temp_cwd = TempDir::new()?; let mut config = (*turn.config).clone(); config.cwd = temp_cwd.abs(); @@ -1464,7 +1464,7 @@ async fn guardian_review_request_layout_matches_model_visible_request_snapshot() .as_deref() .expect("guardian thread id"); assert_eq!(assessment.outcome, GuardianAssessmentOutcome::Allow); - assert_ne!(guardian_thread_id, session.conversation_id.to_string()); + assert_ne!(guardian_thread_id, session.thread_id.to_string()); ThreadId::from_string(guardian_thread_id).expect("guardian thread id should be a valid UUID"); assert!(matches!( metadata.guardian_session_kind, @@ -1567,7 +1567,7 @@ async fn build_guardian_prompt_items_includes_parent_session_id() -> anyhow::Res assert!( prompt_text.contains(&format!( ">>> TRANSCRIPT END\nReviewed Codex session id: {}\n", - session.conversation_id + session.thread_id )), "guardian prompt should expose the parent session id immediately after the transcript end" ); diff --git a/codex-rs/core/src/hook_runtime.rs b/codex-rs/core/src/hook_runtime.rs index 336433fe1..6e2d4fe33 100644 --- a/codex-rs/core/src/hook_runtime.rs +++ b/codex-rs/core/src/hook_runtime.rs @@ -451,7 +451,7 @@ pub(crate) async fn run_legacy_after_agent_hook( triggered_at: chrono::Utc::now(), hook_event: codex_hooks::HookEvent::AfterAgent { event: codex_hooks::HookEventAfterAgent { - thread_id: sess.conversation_id, + thread_id: sess.thread_id, turn_id: turn_context.sub_id.clone(), input_messages, last_assistant_message, @@ -655,7 +655,7 @@ fn track_hook_completed_analytics( completed: &HookCompletedEvent, ) { let (tracking, hook) = - hook_run_analytics_payload(sess.conversation_id.to_string(), turn_context, completed); + hook_run_analytics_payload(sess.thread_id.to_string(), turn_context, completed); sess.services .analytics_events_client .track_hook_run(tracking, hook); diff --git a/codex-rs/core/src/mcp_tool_call.rs b/codex-rs/core/src/mcp_tool_call.rs index 9c00ba2be..b9a8d4ff0 100644 --- a/codex-rs/core/src/mcp_tool_call.rs +++ b/codex-rs/core/src/mcp_tool_call.rs @@ -468,8 +468,8 @@ fn mcp_tool_call_span( mcp.connector.name = fields.connector_name.unwrap_or(""), tool.name = fields.tool_name, tool.call_id = fields.call_id, - conversation.id = %session.conversation_id, - session.id = %session.conversation_id, + conversation.id = %session.thread_id, + session.id = %session.thread_id, turn.id = turn_context.sub_id.as_str(), server.address = Empty, server.port = Empty, @@ -554,8 +554,7 @@ async fn execute_mcp_tool_call( metadata: Option<&McpToolApprovalMetadata>, request_meta: Option, ) -> Result { - let request_meta = - with_mcp_tool_call_thread_id_meta(request_meta, &sess.conversation_id.to_string()); + let request_meta = with_mcp_tool_call_thread_id_meta(request_meta, &sess.thread_id.to_string()); let request_meta = augment_mcp_tool_request_meta_with_sandbox_state( sess, turn_context, @@ -645,7 +644,7 @@ async fn maybe_request_codex_apps_auth_elicitation( let request_id = rmcp::model::RequestId::String(plan.elicitation.elicitation_id.clone().into()); let params = McpServerElicitationRequestParams { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: Some(turn_context.sub_id.clone()), server_name: CODEX_APPS_MCP_SERVER_NAME.to_string(), request: McpServerElicitationRequest::Url { @@ -766,7 +765,7 @@ async fn maybe_mark_thread_memory_mode_polluted( } state_db::mark_thread_memory_mode_polluted( sess.services.state_db.as_deref(), - sess.conversation_id, + sess.thread_id, "mcp_tool_call", ) .await; @@ -945,7 +944,7 @@ async fn maybe_track_codex_app_used( let tracking = build_track_events_context( turn_context.model_info.slug.clone(), - sess.conversation_id.to_string(), + sess.thread_id.to_string(), turn_context.sub_id.clone(), ); sess.services.analytics_events_client.track_app_used( @@ -1615,7 +1614,7 @@ fn build_mcp_tool_approval_elicitation_request( .unwrap_or_else(|| request.question.question.clone()); McpServerElicitationRequestParams { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: Some(turn_context.sub_id.clone()), server_name: request.server.to_string(), request: McpServerElicitationRequest::Form { diff --git a/codex-rs/core/src/mcp_tool_call_tests.rs b/codex-rs/core/src/mcp_tool_call_tests.rs index c9259b8f2..bd71c3a05 100644 --- a/codex-rs/core/src/mcp_tool_call_tests.rs +++ b/codex-rs/core/src/mcp_tool_call_tests.rs @@ -138,7 +138,7 @@ async fn execute_mcp_tool_call_records_replayable_correlation() -> anyhow::Resul .rollout_thread_trace .start_tool_dispatch_trace(|| { Some(ToolDispatchInvocation { - thread_id: session.conversation_id.to_string(), + thread_id: session.thread_id.to_string(), codex_turn_id: turn_context.sub_id.clone(), tool_call_id: "mcp-call".to_string(), tool_name: "search".to_string(), @@ -280,7 +280,7 @@ fn attach_trace_bundle( codex_rollout_trace::ThreadTraceContext::start_root_in_root_for_test( root, ThreadStartedTraceMetadata { - thread_id: session.conversation_id.to_string(), + thread_id: session.thread_id.to_string(), agent_path: "/root".to_string(), task_name: None, nickname: None, @@ -646,7 +646,7 @@ async fn approval_elicitation_request_uses_message_override_and_preserves_tool_p assert_eq!( request, McpServerElicitationRequestParams { - thread_id: session.conversation_id.to_string(), + thread_id: session.thread_id.to_string(), turn_id: Some(turn_context.sub_id), server_name: CODEX_APPS_MCP_SERVER_NAME.to_string(), request: McpServerElicitationRequest::Form { diff --git a/codex-rs/core/src/realtime_conversation.rs b/codex-rs/core/src/realtime_conversation.rs index 7f71142e1..9f35fb2fa 100644 --- a/codex-rs/core/src/realtime_conversation.rs +++ b/codex-rs/core/src/realtime_conversation.rs @@ -716,7 +716,7 @@ pub(crate) async fn build_realtime_session_config( Ok(RealtimeSessionConfig { instructions: prompt, model, - session_id: Some(realtime_session_id.unwrap_or_else(|| sess.conversation_id.to_string())), + session_id: Some(realtime_session_id.unwrap_or_else(|| sess.thread_id.to_string())), event_parser, session_mode, output_modality, diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 5a92c9c82..8ce16de74 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -654,7 +654,7 @@ impl Codex { error!("Failed to create session: {e:#}"); map_session_init_error(&e, &config.codex_home) })?; - let thread_id = session.conversation_id; + let thread_id = session.thread_id; // This task will run until Op::Shutdown is received. let session_for_loop = Arc::clone(&session); @@ -1369,7 +1369,7 @@ impl Session { ShellSnapshot::refresh_snapshot( codex_home.clone(), - self.conversation_id, + self.thread_id, next_cwd.clone(), self.services.user_shell.as_ref().clone(), self.services.shell_snapshot_tx.clone(), @@ -1640,7 +1640,7 @@ impl Session { self.services .analytics_events_client .track_turn_codex_error(TurnCodexErrorFact::from_codex_err( - self.conversation_id.to_string(), + self.thread_id.to_string(), turn_context.sub_id.clone(), error, )); @@ -1819,7 +1819,7 @@ impl Session { self.send_event( turn_context, EventMsg::ItemStarted(ItemStartedEvent { - thread_id: self.conversation_id, + thread_id: self.thread_id, turn_id: turn_context.sub_id.clone(), item: item.clone(), started_at_ms: now_unix_timestamp_ms(), @@ -1837,7 +1837,7 @@ impl Session { self.send_event( turn_context, EventMsg::ItemCompleted(ItemCompletedEvent { - thread_id: self.conversation_id, + thread_id: self.thread_id, turn_id: turn_context.sub_id.clone(), item, completed_at_ms: now_unix_timestamp_ms(), @@ -2900,7 +2900,7 @@ impl Session { let subagents = self .services .agent_control - .format_environment_context_subagents(self.conversation_id) + .format_environment_context_subagents(self.thread_id) .await; contextual_user_sections.push( crate::context::EnvironmentContext::from_turn_context(turn_context, shell.as_ref()) diff --git a/codex-rs/core/src/session/session.rs b/codex-rs/core/src/session/session.rs index 05773abb8..6ab7e86f3 100644 --- a/codex-rs/core/src/session/session.rs +++ b/codex-rs/core/src/session/session.rs @@ -19,7 +19,7 @@ use tokio::sync::Semaphore; /// /// A session has at most 1 running task at a time, and can be interrupted by user input. pub(crate) struct Session { - pub(crate) conversation_id: ThreadId, + pub(crate) thread_id: ThreadId, pub(crate) installation_id: String, pub(super) tx_event: Sender, pub(super) agent_status: watch::Sender, @@ -471,7 +471,7 @@ async fn warm_plugins_and_skills_for_session_init( impl Session { /// Returns the concrete identity for this thread. pub(crate) fn thread_id(&self) -> ThreadId { - self.conversation_id + self.thread_id } /// Returns the identity shared by the root thread and all descendant threads. @@ -1061,7 +1061,7 @@ impl Session { watch::channel(false); let sess = Arc::new(Session { - conversation_id: thread_id, + thread_id, installation_id, tx_event: tx_event.clone(), agent_status, diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index a3e555897..4d4709e65 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -344,7 +344,7 @@ async fn request_mcp_server_elicitation_auto_accepts_when_auto_deny_is_enabled() turn_context.as_ref(), RequestId::String("request-1".into()), McpServerElicitationRequestParams { - thread_id: session.conversation_id.to_string(), + thread_id: session.thread_id.to_string(), turn_id: Some(turn_context.sub_id.clone()), server_name: "codex_apps".to_string(), request: McpServerElicitationRequest::Form { @@ -1333,7 +1333,7 @@ async fn reload_user_config_layer_refreshes_hooks() -> anyhow::Result<()> { }))?; let request = codex_hooks::SessionStartRequest { - session_id: session.conversation_id, + session_id: session.thread_id, cwd: session.get_config().await.cwd.clone(), transcript_path: None, model: "gpt-5.2".to_string(), @@ -1440,7 +1440,7 @@ async fn refresh_runtime_config_refreshes_hooks() -> anyhow::Result<()> { std::fs::write(&config_toml_path, toml::to_string(&trusted_user_config)?)?; let request = codex_hooks::SessionStartRequest { - session_id: session.conversation_id, + session_id: session.thread_id, cwd: session.get_config().await.cwd.clone(), transcript_path: None, model: "gpt-5.2".to_string(), @@ -1999,7 +1999,7 @@ async fn record_token_usage_info_notifies_extension_contributors() { let expected = vec![ RecordedTokenUsage { session_level_id: session.session_id().to_string(), - thread_level_id: session.conversation_id.to_string(), + thread_level_id: session.thread_id.to_string(), turn_level_id: turn_context.sub_id.clone(), token_usage: TokenUsageInfo { total_token_usage: first_usage.clone(), @@ -2011,7 +2011,7 @@ async fn record_token_usage_info_notifies_extension_contributors() { }, RecordedTokenUsage { session_level_id: session.session_id().to_string(), - thread_level_id: session.conversation_id.to_string(), + thread_level_id: session.thread_id.to_string(), turn_level_id: turn_context.sub_id.clone(), token_usage: TokenUsageInfo { total_token_usage: expected_total_usage, @@ -2100,7 +2100,7 @@ async fn turn_start_lifecycle_exposes_turn_metadata_and_token_baseline() { let expected = RecordedTurnStart { session_level_id: session.session_id().to_string(), - thread_level_id: session.conversation_id.to_string(), + thread_level_id: session.thread_id.to_string(), turn_level_id: turn_context.sub_id.clone(), turn_id: turn_context.sub_id.clone(), collaboration_mode: turn_context.collaboration_mode.clone(), @@ -2188,7 +2188,7 @@ async fn turn_error_lifecycle_exposes_error_and_stores() { let expected = RecordedTurnError { session_level_id: session.session_id().to_string(), - thread_level_id: session.conversation_id.to_string(), + thread_level_id: session.thread_id.to_string(), turn_level_id: turn_context.sub_id.clone(), turn_id: turn_context.sub_id.clone(), error: CodexErrorInfo::UsageLimitExceeded, @@ -3539,7 +3539,7 @@ async fn attach_thread_persistence(session: &mut Session) -> PathBuf { let live_thread = LiveThread::create( Arc::clone(&session.services.thread_store), CreateThreadParams { - thread_id: session.conversation_id, + thread_id: session.thread_id, forked_from_id: None, parent_thread_id: None, source: SessionSource::Exec, @@ -4820,7 +4820,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) { ); let session = Session { - conversation_id: thread_id, + thread_id, installation_id: "11111111-1111-4111-8111-111111111111".to_string(), tx_event, agent_status: agent_status_tx, @@ -6282,7 +6282,7 @@ async fn shutdown_complete_does_not_append_to_thread_store_after_shutdown() { let live_thread = LiveThread::create( Arc::clone(&thread_store), CreateThreadParams { - thread_id: session.conversation_id, + thread_id: session.thread_id, forked_from_id: None, parent_thread_id: None, source: SessionSource::Exec, @@ -6347,7 +6347,7 @@ async fn submission_loop_channel_close_emits_thread_stop_lifecycle() { let mut builder = codex_extension_api::ExtensionRegistryBuilder::::new(); builder.thread_lifecycle_contributor(Arc::new(ThreadStopRecorder { calls: Arc::clone(&calls), - expected_thread_id: session.conversation_id, + expected_thread_id: session.thread_id, })); session.services.extensions = Arc::new(builder.build()); session @@ -6409,7 +6409,7 @@ async fn submission_loop_channel_close_aborts_active_turn_before_thread_stop_lif let calls = Arc::new(std::sync::Mutex::new(Vec::new())); let recorder = Arc::new(LifecycleRecorder { calls: Arc::clone(&calls), - expected_thread_id: session.conversation_id, + expected_thread_id: session.thread_id, expected_turn_id: turn_context.sub_id.clone(), }); let mut builder = codex_extension_api::ExtensionRegistryBuilder::::new(); @@ -6910,7 +6910,7 @@ where )); let session = Arc::new(Session { - conversation_id: thread_id, + thread_id, installation_id: "11111111-1111-4111-8111-111111111111".to_string(), tx_event, agent_status: agent_status_tx, @@ -6976,7 +6976,7 @@ async fn upsert_goal_test_thread(session: &Session) { .state_db() .expect("goal test session should have a state db"); let mut builder = codex_state::ThreadMetadataBuilder::new( - session.conversation_id, + session.thread_id, config .codex_home .join("goal-test-rollout.jsonl") @@ -7797,7 +7797,7 @@ async fn handle_output_item_done_records_image_save_history_message() { let call_id = "ig_history_records_message"; let expected_saved_path = crate::stream_events_utils::image_generation_artifact_path( &turn_context.config.codex_home, - &session.conversation_id.to_string(), + &session.thread_id.to_string(), call_id, ); let _ = std::fs::remove_file(&expected_saved_path); @@ -7824,7 +7824,7 @@ async fn handle_output_item_done_records_image_save_history_message() { let history = session.clone_history().await; let image_output_path = crate::stream_events_utils::image_generation_artifact_path( &turn_context.config.codex_home, - &session.conversation_id.to_string(), + &session.thread_id.to_string(), "", ); let image_output_dir = image_output_path @@ -7852,7 +7852,7 @@ async fn handle_output_item_done_skips_image_save_message_when_save_fails() { let call_id = "ig_history_no_message"; let expected_saved_path = crate::stream_events_utils::image_generation_artifact_path( &turn_context.config.codex_home, - &session.conversation_id.to_string(), + &session.thread_id.to_string(), call_id, ); let _ = std::fs::remove_file(&expected_saved_path); @@ -8698,7 +8698,7 @@ async fn task_finish_emits_thread_idle_lifecycle_after_active_turn_clears() { builder.thread_lifecycle_contributor(Arc::new(ThreadIdleRecorder { calls: Arc::clone(&calls), idle_tx, - expected_thread_id: session.conversation_id, + expected_thread_id: session.thread_id, })); session.services.extensions = Arc::new(builder.build()); @@ -9321,7 +9321,7 @@ async fn create_thread_goal_fills_empty_thread_preview() -> anyhow::Result<()> { .iter() .map(|thread| thread.id) .collect::>(); - assert_eq!(vec![sess.conversation_id], ids); + assert_eq!(vec![sess.thread_id], ids); assert_eq!( Some("Keep improving the benchmark"), page.items[0].preview.as_deref() @@ -9401,7 +9401,7 @@ async fn budget_limited_accounting_steers_active_turn_without_aborting() -> anyh let state_db = goal_test_state_db(sess.as_ref()).await?; let goal = state_db .thread_goals() - .get_thread_goal(sess.conversation_id) + .get_thread_goal(sess.thread_id) .await? .expect("goal should remain persisted after accounting"); assert_eq!(codex_state::ThreadGoalStatus::BudgetLimited, goal.status); @@ -9425,7 +9425,7 @@ async fn budget_limited_accounting_steers_active_turn_without_aborting() -> anyh let goal = state_db .thread_goals() - .get_thread_goal(sess.conversation_id) + .get_thread_goal(sess.thread_id) .await? .expect("goal should remain persisted after follow-up accounting"); assert_eq!(codex_state::ThreadGoalStatus::BudgetLimited, goal.status); @@ -9473,7 +9473,7 @@ async fn usage_limit_runtime_stops_active_goal_and_prevents_idle_continuation() let state_db = goal_test_state_db(sess.as_ref()).await?; let goal = state_db .thread_goals() - .get_thread_goal(sess.conversation_id) + .get_thread_goal(sess.thread_id) .await? .expect("goal should remain persisted after usage limiting"); assert_eq!(codex_state::ThreadGoalStatus::UsageLimited, goal.status); @@ -9516,7 +9516,7 @@ async fn external_goal_mutation_accounts_active_turn_before_status_change() -> a let state_db = goal_test_state_db(sess.as_ref()).await?; let goal = state_db .thread_goals() - .get_thread_goal(sess.conversation_id) + .get_thread_goal(sess.thread_id) .await? .expect("goal should remain persisted"); assert_eq!(70, goal.tokens_used); @@ -9526,7 +9526,7 @@ async fn external_goal_mutation_accounts_active_turn_before_status_change() -> a let updated_goal = state_db .thread_goals() .update_thread_goal( - sess.conversation_id, + sess.thread_id, codex_state::GoalUpdate { objective: None, status: Some(codex_state::ThreadGoalStatus::Complete), @@ -9547,7 +9547,7 @@ async fn external_goal_mutation_accounts_active_turn_before_status_change() -> a assert!(sess.active_turn.lock().await.is_some()); let goal = state_db .thread_goals() - .get_thread_goal(sess.conversation_id) + .get_thread_goal(sess.thread_id) .await? .expect("goal should remain persisted"); assert_eq!(codex_state::ThreadGoalStatus::Complete, goal.status); @@ -9575,7 +9575,7 @@ async fn external_objective_change_steers_active_turn() -> anyhow::Result<()> { let old_goal = state_db .thread_goals() .replace_thread_goal( - sess.conversation_id, + sess.thread_id, "Keep improving the benchmark", codex_state::ThreadGoalStatus::Active, /*token_budget*/ Some(10_000), @@ -9584,7 +9584,7 @@ async fn external_objective_change_steers_active_turn() -> anyhow::Result<()> { let new_goal = state_db .thread_goals() .replace_thread_goal( - sess.conversation_id, + sess.thread_id, "Write a concise benchmark summary", codex_state::ThreadGoalStatus::Active, /*token_budget*/ Some(10_000), @@ -9642,7 +9642,7 @@ async fn external_active_goal_set_marks_current_turn_for_accounting() -> anyhow: let goal = state_db .thread_goals() .replace_thread_goal( - sess.conversation_id, + sess.thread_id, "Keep improving the benchmark", codex_state::ThreadGoalStatus::Active, /*token_budget*/ None, @@ -9675,7 +9675,7 @@ async fn external_active_goal_set_marks_current_turn_for_accounting() -> anyhow: let goal = state_db .thread_goals() - .get_thread_goal(sess.conversation_id) + .get_thread_goal(sess.thread_id) .await? .expect("goal should remain persisted"); assert_eq!(codex_state::ThreadGoalStatus::Active, goal.status); diff --git a/codex-rs/core/src/session/turn.rs b/codex-rs/core/src/session/turn.rs index e301a9c04..42d609561 100644 --- a/codex-rs/core/src/session/turn.rs +++ b/codex-rs/core/src/session/turn.rs @@ -469,7 +469,7 @@ async fn build_skills_and_plugins( .collect::>(); let tracking = build_track_events_context( turn_context.model_info.slug.clone(), - sess.conversation_id.to_string(), + sess.thread_id.to_string(), turn_context.sub_id.clone(), ); let loaded_plugins = sess @@ -665,7 +665,7 @@ async fn track_turn_resolved_config_analytics( .analytics_events_client .track_turn_resolved_config(TurnResolvedConfigFact { turn_id: turn_context.sub_id.clone(), - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), num_input_images: input .iter() .filter_map(|item| match item { @@ -1306,7 +1306,7 @@ impl ProposedPlanItemState { return; } let event = PlanDeltaEvent { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: turn_context.sub_id.clone(), item_id: self.item_id.clone(), delta: delta.to_string(), @@ -1482,7 +1482,7 @@ async fn handle_plan_segments( maybe_emit_pending_agent_message_start(sess, turn_context, state, item_id).await; let event = AgentMessageContentDeltaEvent { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: turn_context.sub_id.clone(), item_id: item_id.to_string(), delta, @@ -1536,7 +1536,7 @@ async fn emit_streamed_assistant_text_delta( return; } let event = AgentMessageContentDeltaEvent { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: turn_context.sub_id.clone(), item_id: item_id.to_string(), delta: parsed.visible_text, @@ -2102,7 +2102,7 @@ async fn try_run_sampling_request( .await; } else { let event = AgentMessageContentDeltaEvent { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: turn_context.sub_id.clone(), item_id, delta, @@ -2141,7 +2141,7 @@ async fn try_run_sampling_request( continue; } let event = ReasoningContentDeltaEvent { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: turn_context.sub_id.clone(), item_id: active.id(), delta, @@ -2177,7 +2177,7 @@ async fn try_run_sampling_request( continue; } let event = ReasoningRawContentDeltaEvent { - thread_id: sess.conversation_id.to_string(), + thread_id: sess.thread_id.to_string(), turn_id: turn_context.sub_id.clone(), item_id: active.id(), delta, diff --git a/codex-rs/core/src/skills.rs b/codex-rs/core/src/skills.rs index d540cd6d4..b11f79260 100644 --- a/codex-rs/core/src/skills.rs +++ b/codex-rs/core/src/skills.rs @@ -100,7 +100,7 @@ pub(crate) async fn maybe_emit_implicit_skill_invocation( .track_skill_invocations( build_track_events_context( turn_context.model_info.slug.clone(), - sess.conversation_id.to_string(), + sess.thread_id.to_string(), turn_context.sub_id.clone(), ), vec![invocation], diff --git a/codex-rs/core/src/stream_events_utils.rs b/codex-rs/core/src/stream_events_utils.rs index 7914c8d48..20fc6787a 100644 --- a/codex-rs/core/src/stream_events_utils.rs +++ b/codex-rs/core/src/stream_events_utils.rs @@ -132,7 +132,7 @@ pub(crate) async fn persist_image_generation_item( image_item: &mut ImageGenerationItem, ) -> Option { image_item.saved_path = None; - let session_id = sess.conversation_id.to_string(); + let session_id = sess.thread_id.to_string(); match save_image_generation_result( &turn_context.config.codex_home, &session_id, @@ -172,7 +172,7 @@ async fn record_image_generation_instructions( if image_item.saved_path.is_none() { return; } - let session_id = sess.conversation_id.to_string(); + let session_id = sess.thread_id.to_string(); let image_output_path = image_generation_artifact_path(&turn_context.config.codex_home, &session_id, ""); let image_output_dir = image_output_path @@ -263,7 +263,7 @@ pub(crate) async fn mark_thread_memory_mode_polluted_if_external_context( } state_db::mark_thread_memory_mode_polluted( sess.services.state_db.as_deref(), - sess.conversation_id, + sess.thread_id, "record_completed_response_item", ) .await; @@ -422,7 +422,7 @@ pub(crate) async fn handle_output_item_done( let payload_preview = call.payload.log_payload().into_owned(); tracing::info!( - thread_id = %ctx.sess.conversation_id, + thread_id = %ctx.sess.thread_id, "ToolCall: {} {}", call.tool_name, payload_preview diff --git a/codex-rs/core/src/tasks/mod.rs b/codex-rs/core/src/tasks/mod.rs index 76d5e6478..ef2ba0f16 100644 --- a/codex-rs/core/src/tasks/mod.rs +++ b/codex-rs/core/src/tasks/mod.rs @@ -383,7 +383,7 @@ impl Session { let task_span = info_span!( "turn", otel.name = span_name, - thread.id = %self.conversation_id, + thread.id = %self.thread_id, turn.id = %turn_context.sub_id, model = %turn_context.model_info.slug, codex.turn.reasoning_effort = %reasoning_effort, @@ -708,7 +708,7 @@ impl Session { .analytics_events_client .track_turn_token_usage(TurnTokenUsageFact { turn_id: turn_context.sub_id.clone(), - thread_id: self.conversation_id.to_string(), + thread_id: self.thread_id.to_string(), token_usage: turn_token_usage.clone(), }); self.services.session_telemetry.histogram( diff --git a/codex-rs/core/src/tasks/user_shell.rs b/codex-rs/core/src/tasks/user_shell.rs index 15778b64d..e016a725c 100644 --- a/codex-rs/core/src/tasks/user_shell.rs +++ b/codex-rs/core/src/tasks/user_shell.rs @@ -126,7 +126,7 @@ pub(crate) async fn execute_user_shell_command( let display_command = session_shell.derive_exec_args(&command, use_login_shell); let mut exec_env_map = create_env( &turn_context.shell_environment_policy, - Some(session.conversation_id), + Some(session.thread_id), ); if exec_env_map.contains_key(PROXY_ACTIVE_ENV_KEY) { strip_managed_proxy_env(&mut exec_env_map); diff --git a/codex-rs/core/src/tools/handlers/agent_jobs.rs b/codex-rs/core/src/tools/handlers/agent_jobs.rs index 48ba08743..25c8f9c4c 100644 --- a/codex-rs/core/src/tools/handlers/agent_jobs.rs +++ b/codex-rs/core/src/tools/handlers/agent_jobs.rs @@ -211,7 +211,7 @@ async fn run_agent_job_loop( "agent_job:{job_id}" )))), SpawnAgentOptions { - parent_thread_id: Some(session.conversation_id), + parent_thread_id: Some(session.thread_id), environments: Some(turn.environments.to_selections()), ..Default::default() }, diff --git a/codex-rs/core/src/tools/handlers/agent_jobs/report_agent_job_result.rs b/codex-rs/core/src/tools/handlers/agent_jobs/report_agent_job_result.rs index 6f4463c6e..c7adb2761 100644 --- a/codex-rs/core/src/tools/handlers/agent_jobs/report_agent_job_result.rs +++ b/codex-rs/core/src/tools/handlers/agent_jobs/report_agent_job_result.rs @@ -61,7 +61,7 @@ pub async fn handle( )); } let db = required_state_db(&session)?; - let reporting_thread_id = session.conversation_id.to_string(); + let reporting_thread_id = session.thread_id.to_string(); let accepted = db .report_agent_job_item_result( args.job_id.as_str(), diff --git a/codex-rs/core/src/tools/handlers/extension_tools.rs b/codex-rs/core/src/tools/handlers/extension_tools.rs index 0a1e2e58c..ecbf772e9 100644 --- a/codex-rs/core/src/tools/handlers/extension_tools.rs +++ b/codex-rs/core/src/tools/handlers/extension_tools.rs @@ -486,7 +486,7 @@ mod tests { let (session, turn, rx) = crate::session::tests::make_session_and_context_with_rx().await; let expected_path = crate::stream_events_utils::image_generation_artifact_path( &turn.config.codex_home, - &session.conversation_id.to_string(), + &session.thread_id.to_string(), "call-image", ); let invocation = ToolInvocation { diff --git a/codex-rs/core/src/tools/handlers/multi_agents/close_agent.rs b/codex-rs/core/src/tools/handlers/multi_agents/close_agent.rs index 2007e3df7..0d4e17447 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents/close_agent.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents/close_agent.rs @@ -53,7 +53,7 @@ async fn handle_close_agent( CollabCloseBeginEvent { call_id: call_id.clone(), started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id: agent_id, } .into(), @@ -77,7 +77,7 @@ async fn handle_close_agent( CollabCloseEndEvent { call_id: call_id.clone(), completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id(), receiver_thread_id: agent_id, receiver_agent_nickname: receiver_agent.agent_nickname.clone(), receiver_agent_role: receiver_agent.agent_role.clone(), @@ -99,7 +99,7 @@ async fn handle_close_agent( CollabCloseEndEvent { call_id, completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id: agent_id, receiver_agent_nickname: receiver_agent.agent_nickname, receiver_agent_role: receiver_agent.agent_role, diff --git a/codex-rs/core/src/tools/handlers/multi_agents/resume_agent.rs b/codex-rs/core/src/tools/handlers/multi_agents/resume_agent.rs index 78b6aafb9..8f95abe4e 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents/resume_agent.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents/resume_agent.rs @@ -66,7 +66,7 @@ async fn handle_resume_agent( CollabResumeBeginEvent { call_id: call_id.clone(), started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id, receiver_agent_nickname: receiver_agent.agent_nickname.clone(), receiver_agent_role: receiver_agent.agent_role.clone(), @@ -122,7 +122,7 @@ async fn handle_resume_agent( CollabResumeEndEvent { call_id, completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id(), receiver_thread_id, receiver_agent_nickname: receiver_agent.agent_nickname, receiver_agent_role: receiver_agent.agent_role, @@ -186,7 +186,7 @@ async fn try_resume_closed_agent( config, receiver_thread_id, thread_spawn_source( - session.conversation_id, + session.thread_id(), &turn.session_source, child_depth, /*agent_role*/ None, diff --git a/codex-rs/core/src/tools/handlers/multi_agents/send_input.rs b/codex-rs/core/src/tools/handlers/multi_agents/send_input.rs index d7f316ba3..1b7018939 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents/send_input.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents/send_input.rs @@ -58,7 +58,7 @@ impl ToolExecutor for Handler { CollabAgentInteractionBeginEvent { call_id: call_id.clone(), started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id, prompt: prompt.clone(), } @@ -81,7 +81,7 @@ impl ToolExecutor for Handler { CollabAgentInteractionEndEvent { call_id, completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id, receiver_agent_nickname: receiver_agent.agent_nickname, receiver_agent_role: receiver_agent.agent_role, diff --git a/codex-rs/core/src/tools/handlers/multi_agents/spawn.rs b/codex-rs/core/src/tools/handlers/multi_agents/spawn.rs index 108ddd336..004dc973b 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents/spawn.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents/spawn.rs @@ -80,7 +80,7 @@ async fn handle_spawn_agent( CollabAgentSpawnBeginEvent { call_id: call_id.clone(), started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, prompt: prompt.clone(), model: args.model.clone().unwrap_or_default(), reasoning_effort: args.reasoning_effort.unwrap_or_default(), @@ -121,7 +121,7 @@ async fn handle_spawn_agent( config, input_items, Some(thread_spawn_source( - session.conversation_id, + session.thread_id, &turn.session_source, child_depth, role_name, @@ -130,7 +130,7 @@ async fn handle_spawn_agent( SpawnAgentOptions { fork_parent_spawn_call_id: args.fork_context.then(|| call_id.clone()), fork_mode: args.fork_context.then_some(SpawnAgentForkMode::FullHistory), - parent_thread_id: Some(session.conversation_id), + parent_thread_id: Some(session.thread_id), environments: Some(turn.environments.to_selections()), }, )) @@ -183,7 +183,7 @@ async fn handle_spawn_agent( CollabAgentSpawnEndEvent { call_id, completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, new_thread_id, new_agent_nickname, new_agent_role, diff --git a/codex-rs/core/src/tools/handlers/multi_agents/wait.rs b/codex-rs/core/src/tools/handlers/multi_agents/wait.rs index 063b06457..525ee7f2e 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents/wait.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents/wait.rs @@ -96,7 +96,7 @@ impl ToolExecutor for Handler { &turn, CollabWaitingBeginEvent { started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_ids: receiver_thread_ids.clone(), receiver_agents: receiver_agents.clone(), call_id: call_id.clone(), @@ -126,7 +126,7 @@ impl ToolExecutor for Handler { .send_event( &turn, CollabWaitingEndEvent { - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, call_id: call_id.clone(), completed_at_ms: now_unix_timestamp_ms(), agent_statuses: build_wait_agent_statuses( @@ -195,7 +195,7 @@ impl ToolExecutor for Handler { .send_event( &turn, CollabWaitingEndEvent { - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, call_id, completed_at_ms: now_unix_timestamp_ms(), agent_statuses, diff --git a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs index 3d8e8401b..868847414 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -310,7 +310,7 @@ async fn spawn_agent_fork_context_rejects_agent_type_override() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let err = SpawnAgentHandler::default() .handle(invocation( Arc::new(session), @@ -343,7 +343,7 @@ async fn spawn_agent_fork_context_rejects_child_model_overrides() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let err = SpawnAgentHandler::default() .handle(invocation( @@ -379,7 +379,7 @@ async fn multi_agent_v2_spawn_fork_turns_all_rejects_agent_type_override() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -424,7 +424,7 @@ async fn multi_agent_v2_spawn_defaults_to_full_fork_and_rejects_child_model_over .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -471,7 +471,7 @@ async fn spawn_agent_service_tier_override_validates_the_effective_child_model() .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let output = SpawnAgentHandler::default() .handle(invocation( @@ -576,7 +576,7 @@ async fn spawn_agent_service_tier_inheritance_preserves_supported_or_configured_ .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let output = SpawnAgentHandler::default() .handle(invocation( @@ -617,7 +617,7 @@ async fn spawn_agent_service_tier_inheritance_preserves_supported_or_configured_ .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let output = SpawnAgentHandler::default() .handle(invocation( @@ -680,7 +680,7 @@ service_tier = "priority" .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let output = SpawnAgentHandler::default() .handle(invocation( @@ -753,7 +753,7 @@ service_tier = "turbo" .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let output = SpawnAgentHandler::default() .handle(invocation( @@ -850,7 +850,7 @@ async fn spawn_agent_full_history_fork_accepts_explicit_service_tier() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let output = SpawnAgentHandler::default() .handle(invocation( @@ -904,7 +904,7 @@ async fn multi_agent_v2_full_history_fork_accepts_explicit_service_tier() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let session = Arc::new(session); let turn = Arc::new(turn); @@ -928,7 +928,7 @@ async fn multi_agent_v2_full_history_fork_accepts_explicit_service_tier() { .services .agent_control .resolve_agent_reference( - session.conversation_id, + session.thread_id, &turn.session_source, result.task_name.as_str(), ) @@ -957,7 +957,7 @@ async fn multi_agent_v2_spawn_partial_fork_turns_allows_agent_type_override() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -1041,7 +1041,7 @@ async fn multi_agent_v2_spawn_requires_task_name() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -1075,7 +1075,7 @@ async fn multi_agent_v2_spawn_rejects_legacy_items_field() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -1135,7 +1135,7 @@ async fn multi_agent_v2_spawn_returns_path_and_send_message_accepts_relative_pat .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -1166,11 +1166,7 @@ async fn multi_agent_v2_spawn_returns_path_and_send_message_accepts_relative_pat let child_thread_id = session .services .agent_control - .resolve_agent_reference( - session.conversation_id, - &turn.session_source, - "test_process", - ) + .resolve_agent_reference(session.thread_id, &turn.session_source, "test_process") .await .expect("relative path should resolve"); let child_snapshot = manager @@ -1232,7 +1228,7 @@ async fn multi_agent_v2_spawn_rejects_legacy_fork_context() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -1272,7 +1268,7 @@ async fn multi_agent_v2_spawn_rejects_invalid_fork_turns_string() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -1312,7 +1308,7 @@ async fn multi_agent_v2_spawn_rejects_zero_fork_turns() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -1358,7 +1354,7 @@ async fn multi_agent_v2_send_message_accepts_root_target_from_child() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let child_path = AgentPath::try_from("/root/worker").expect("agent path"); let child_thread_id = session @@ -1383,7 +1379,7 @@ async fn multi_agent_v2_send_message_accepts_root_target_from_child() { .await .expect("worker spawn should succeed") .thread_id; - session.conversation_id = child_thread_id; + session.thread_id = child_thread_id; turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn { parent_thread_id: root.thread_id, depth: 1, @@ -1434,7 +1430,7 @@ async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let child_path = AgentPath::try_from("/root/worker").expect("agent path"); let child_thread_id = session @@ -1459,7 +1455,7 @@ async fn multi_agent_v2_followup_task_rejects_root_target_from_child() { .await .expect("worker spawn should succeed") .thread_id; - session.conversation_id = child_thread_id; + session.thread_id = child_thread_id; turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn { parent_thread_id: root.thread_id, depth: 1, @@ -1511,7 +1507,7 @@ async fn multi_agent_v2_list_agents_returns_completed_status_and_last_task_messa .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); let _ = config.features.enable(Feature::MultiAgentV2); set_turn_config(&mut turn, config); @@ -1535,7 +1531,7 @@ async fn multi_agent_v2_list_agents_returns_completed_status_and_last_task_messa let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker path should resolve"); let child_thread = manager @@ -1608,7 +1604,7 @@ async fn multi_agent_v2_list_agents_filters_by_relative_path_prefix() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let researcher_path = AgentPath::from_string("/root/researcher".to_string()).expect("path"); let worker_path = AgentPath::from_string("/root/researcher/worker".to_string()).expect("path"); @@ -1692,7 +1688,7 @@ async fn multi_agent_v2_list_agents_omits_closed_agents() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); let _ = config.features.enable(Feature::MultiAgentV2); set_turn_config(&mut turn, config); @@ -1716,7 +1712,7 @@ async fn multi_agent_v2_list_agents_omits_closed_agents() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker path should resolve"); session @@ -1756,7 +1752,7 @@ async fn multi_agent_v2_send_message_rejects_legacy_items_field() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = turn.config.as_ref().clone(); let _ = config.features.enable(Feature::MultiAgentV2); set_turn_config(&mut turn, config); @@ -1778,7 +1774,7 @@ async fn multi_agent_v2_send_message_rejects_legacy_items_field() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); let invocation = invocation( @@ -1812,7 +1808,7 @@ async fn multi_agent_v2_send_message_rejects_interrupt_parameter() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = turn.config.as_ref().clone(); let _ = config.features.enable(Feature::MultiAgentV2); set_turn_config(&mut turn, config); @@ -1834,7 +1830,7 @@ async fn multi_agent_v2_send_message_rejects_interrupt_parameter() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); @@ -1891,7 +1887,7 @@ async fn multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn() // and stored its runtime; mirror that before using the synthetic handler. root.thread.codex.session.new_default_turn().await; session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let session = Arc::new(session); let turn = Arc::new(turn); @@ -1910,7 +1906,7 @@ async fn multi_agent_v2_followup_task_completion_notifies_parent_on_every_turn() let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); let thread = manager @@ -2023,7 +2019,7 @@ async fn multi_agent_v2_followup_task_rejects_legacy_items_field() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = turn.config.as_ref().clone(); let _ = config.features.enable(Feature::MultiAgentV2); set_turn_config(&mut turn, config); @@ -2045,7 +2041,7 @@ async fn multi_agent_v2_followup_task_rejects_legacy_items_field() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); let invocation = invocation( @@ -2076,7 +2072,7 @@ async fn multi_agent_v2_interrupted_turn_does_not_notify_parent() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = turn.config.as_ref().clone(); let _ = config.features.enable(Feature::MultiAgentV2); set_turn_config(&mut turn, config); @@ -2098,7 +2094,7 @@ async fn multi_agent_v2_interrupted_turn_does_not_notify_parent() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); let thread = manager @@ -2153,7 +2149,7 @@ async fn multi_agent_v2_spawn_omits_agent_id_when_named() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -2192,7 +2188,7 @@ async fn multi_agent_v2_spawn_surfaces_task_name_validation_errors() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -2316,7 +2312,7 @@ async fn spawn_agent_rejects_when_depth_limit_exceeded() { let max_depth = turn.config.agent_max_depth; turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn { - parent_thread_id: session.conversation_id, + parent_thread_id: session.thread_id, depth: max_depth, agent_path: None, agent_nickname: None, @@ -2356,7 +2352,7 @@ async fn spawn_agent_allows_depth_up_to_configured_max_depth() { config.agent_max_depth = DEFAULT_AGENT_MAX_DEPTH + 1; turn.config = Arc::new(config); turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn { - parent_thread_id: session.conversation_id, + parent_thread_id: session.thread_id, depth: DEFAULT_AGENT_MAX_DEPTH, agent_path: None, agent_nickname: None, @@ -2407,7 +2403,7 @@ async fn multi_agent_v2_spawn_agent_ignores_configured_max_depth() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; set_turn_config(&mut turn, config); let parent_path = AgentPath::try_from("/root/parent").expect("agent path"); turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn { @@ -2785,7 +2781,7 @@ async fn resume_agent_rejects_when_depth_limit_exceeded() { let max_depth = turn.config.agent_max_depth; turn.session_source = SessionSource::SubAgent(SubAgentSource::ThreadSpawn { - parent_thread_id: session.conversation_id, + parent_thread_id: session.thread_id, depth: max_depth, agent_path: None, agent_nickname: None, @@ -2875,7 +2871,7 @@ async fn multi_agent_v2_wait_agent_accepts_timeout_only_argument() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -2900,7 +2896,7 @@ async fn multi_agent_v2_wait_agent_accepts_timeout_only_argument() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); let worker_path = session @@ -3358,7 +3354,7 @@ async fn multi_agent_v2_wait_agent_returns_summary_for_mailbox_activity() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -3385,11 +3381,7 @@ async fn multi_agent_v2_wait_agent_returns_summary_for_mailbox_activity() { let agent_id = session .services .agent_control - .resolve_agent_reference( - session.conversation_id, - &turn.session_source, - "test_process", - ) + .resolve_agent_reference(session.thread_id, &turn.session_source, "test_process") .await .expect("relative path should resolve"); let worker_path = session @@ -3452,7 +3444,7 @@ async fn multi_agent_v2_wait_agent_returns_for_already_queued_mail() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -3477,7 +3469,7 @@ async fn multi_agent_v2_wait_agent_returns_for_already_queued_mail() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); let worker_path = session @@ -3533,7 +3525,7 @@ async fn multi_agent_v2_wait_agent_wakes_on_any_mailbox_notification() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -3560,7 +3552,7 @@ async fn multi_agent_v2_wait_agent_wakes_on_any_mailbox_notification() { let worker_b_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker_b") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker_b") .await .expect("worker_b should resolve"); let worker_b_path = session @@ -3624,7 +3616,7 @@ async fn multi_agent_v2_wait_agent_does_not_return_completed_content() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -3649,7 +3641,7 @@ async fn multi_agent_v2_wait_agent_does_not_return_completed_content() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker should resolve"); let worker_path = session @@ -3713,7 +3705,7 @@ async fn multi_agent_v2_close_agent_accepts_task_name_target() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features @@ -3739,7 +3731,7 @@ async fn multi_agent_v2_close_agent_accepts_task_name_target() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker path should resolve"); @@ -3791,7 +3783,7 @@ async fn multi_agent_v2_close_agent_reaps_stale_task_name_target() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; set_turn_config(&mut turn, config.clone()); let session = Arc::new(session); @@ -3812,7 +3804,7 @@ async fn multi_agent_v2_close_agent_reaps_stale_task_name_target() { let agent_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "worker") + .resolve_agent_reference(session.thread_id, &turn.session_source, "worker") .await .expect("worker path should resolve"); let stale_thread = manager @@ -3872,7 +3864,7 @@ async fn multi_agent_v2_close_agent_reaps_stale_task_name_target() { let replacement_id = session .services .agent_control - .resolve_agent_reference(session.conversation_id, &turn.session_source, "replacement") + .resolve_agent_reference(session.thread_id, &turn.session_source, "replacement") .await .expect("replacement path should resolve"); let _ = session @@ -3892,7 +3884,7 @@ async fn multi_agent_v2_close_agent_rejects_root_target_and_id() { .await .expect("root thread should start"); session.services.agent_control = manager.agent_control(); - session.conversation_id = root.thread_id; + session.thread_id = root.thread_id; let mut config = (*turn.config).clone(); config .features diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/close_agent.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/close_agent.rs index 0f7238cdb..756a1862b 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/close_agent.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/close_agent.rs @@ -61,7 +61,7 @@ async fn handle_close_agent( CollabCloseBeginEvent { call_id: call_id.clone(), started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id: agent_id, } .into(), @@ -85,7 +85,7 @@ async fn handle_close_agent( CollabCloseEndEvent { call_id: call_id.clone(), completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id: agent_id, receiver_agent_nickname: receiver_agent.agent_nickname.clone(), receiver_agent_role: receiver_agent.agent_role.clone(), @@ -110,7 +110,7 @@ async fn handle_close_agent( CollabCloseEndEvent { call_id, completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id: agent_id, receiver_agent_nickname: receiver_agent.agent_nickname, receiver_agent_role: receiver_agent.agent_role, diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/list_agents.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/list_agents.rs index 6abf9a30c..46b29bdf1 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/list_agents.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/list_agents.rs @@ -30,7 +30,7 @@ impl ToolExecutor for Handler { session .services .agent_control - .register_session_root(session.conversation_id, turn.parent_thread_id); + .register_session_root(session.thread_id, turn.parent_thread_id); let agents = session .services .agent_control diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs index 3226c4532..258d80c85 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/message_tool.rs @@ -91,7 +91,7 @@ pub(crate) async fn handle_message_string_tool( CollabAgentInteractionBeginEvent { call_id: call_id.clone(), started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id, prompt: prompt.clone(), } @@ -127,7 +127,7 @@ pub(crate) async fn handle_message_string_tool( CollabAgentInteractionEndEvent { call_id, completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_id, receiver_agent_nickname: receiver_agent.agent_nickname, receiver_agent_role: receiver_agent.agent_role, diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs index ed85d329b..d0fb6c515 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs @@ -72,7 +72,7 @@ async fn handle_spawn_agent( CollabAgentSpawnBeginEvent { call_id: call_id.clone(), started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, prompt: prompt.clone(), model: args.model.clone().unwrap_or_default(), reasoning_effort: args.reasoning_effort.unwrap_or_default(), @@ -110,7 +110,7 @@ async fn handle_spawn_agent( apply_spawn_agent_runtime_overrides(&mut config, turn.as_ref())?; let spawn_source = thread_spawn_source( - session.conversation_id, + session.thread_id, &turn.session_source, child_depth, role_name, @@ -143,7 +143,7 @@ async fn handle_spawn_agent( SpawnAgentOptions { fork_parent_spawn_call_id: fork_mode.as_ref().map(|_| call_id.clone()), fork_mode, - parent_thread_id: Some(session.conversation_id), + parent_thread_id: Some(session.thread_id), environments: Some(turn.environments.to_selections()), }, ), @@ -197,7 +197,7 @@ async fn handle_spawn_agent( CollabAgentSpawnEndEvent { call_id, completed_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, new_thread_id, new_agent_nickname, new_agent_role, diff --git a/codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rs b/codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rs index 0aba86782..5e37725b7 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_v2/wait.rs @@ -67,7 +67,7 @@ impl ToolExecutor for Handler { &turn, CollabWaitingBeginEvent { started_at_ms: now_unix_timestamp_ms(), - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, receiver_thread_ids: Vec::new(), receiver_agents: Vec::new(), call_id: call_id.clone(), @@ -84,7 +84,7 @@ impl ToolExecutor for Handler { .send_event( &turn, CollabWaitingEndEvent { - sender_thread_id: session.conversation_id, + sender_thread_id: session.thread_id, call_id, completed_at_ms: now_unix_timestamp_ms(), agent_statuses: Vec::new(), diff --git a/codex-rs/core/src/tools/handlers/request_plugin_install.rs b/codex-rs/core/src/tools/handlers/request_plugin_install.rs index 51032b27c..3f7bd92d2 100644 --- a/codex-rs/core/src/tools/handlers/request_plugin_install.rs +++ b/codex-rs/core/src/tools/handlers/request_plugin_install.rs @@ -121,7 +121,7 @@ impl ToolExecutor for RequestPluginInstallHandler { let request_id = RequestId::String(format!("request_plugin_install_{call_id}").into()); let params = build_request_plugin_install_elicitation_request( CODEX_APPS_MCP_SERVER_NAME, - session.conversation_id.to_string(), + session.thread_id.to_string(), turn.sub_id.clone(), &args, suggest_reason, diff --git a/codex-rs/core/src/tools/handlers/shell/shell_command.rs b/codex-rs/core/src/tools/handlers/shell/shell_command.rs index 8a501c711..b4b60997d 100644 --- a/codex-rs/core/src/tools/handlers/shell/shell_command.rs +++ b/codex-rs/core/src/tools/handlers/shell/shell_command.rs @@ -179,7 +179,7 @@ impl ToolExecutor for ShellCommandHandler { ¶ms, session.as_ref(), turn.as_ref(), - session.conversation_id, + session.thread_id, turn.config.permissions.allow_login_shell, )?; let shell_type = Some(session.user_shell().shell_type.clone()); diff --git a/codex-rs/core/src/tools/handlers/shell_tests.rs b/codex-rs/core/src/tools/handlers/shell_tests.rs index eda23533a..792eb2bb1 100644 --- a/codex-rs/core/src/tools/handlers/shell_tests.rs +++ b/codex-rs/core/src/tools/handlers/shell_tests.rs @@ -92,7 +92,7 @@ async fn shell_command_handler_to_exec_params_uses_session_shell_and_turn_contex let expected_cwd = turn_context.resolve_path(workdir.clone()); let expected_env = create_env( &turn_context.shell_environment_policy, - Some(session.conversation_id), + Some(session.thread_id), ); let params = ShellCommandToolCallParams { @@ -110,7 +110,7 @@ async fn shell_command_handler_to_exec_params_uses_session_shell_and_turn_contex ¶ms, &session, &turn_context, - session.conversation_id, + session.thread_id, /*allow_login_shell*/ true, ) .expect("login shells should be allowed"); @@ -177,7 +177,7 @@ async fn shell_command_handler_defaults_to_non_login_when_disallowed() { ¶ms, &session, &turn_context, - session.conversation_id, + session.thread_id, /*allow_login_shell*/ false, ) .expect("non-login shells should still be allowed"); diff --git a/codex-rs/core/src/tools/tool_dispatch_trace.rs b/codex-rs/core/src/tools/tool_dispatch_trace.rs index 522e3cd1d..098dc8dde 100644 --- a/codex-rs/core/src/tools/tool_dispatch_trace.rs +++ b/codex-rs/core/src/tools/tool_dispatch_trace.rs @@ -74,7 +74,7 @@ fn tool_dispatch_invocation(invocation: &ToolInvocation) -> Option anyhow::Result<()> { - let thread_id = session.conversation_id; + let thread_id = session.thread_id; let rollout_thread_trace = codex_rollout_trace::ThreadTraceContext::start_root_in_root_for_test( root, diff --git a/codex-rs/core/src/unified_exec/process_manager.rs b/codex-rs/core/src/unified_exec/process_manager.rs index 563d486c6..66b8b49a8 100644 --- a/codex-rs/core/src/unified_exec/process_manager.rs +++ b/codex-rs/core/src/unified_exec/process_manager.rs @@ -1002,7 +1002,7 @@ impl UnifiedExecProcessManager { let mut env = local_policy_env.clone(); env.insert( CODEX_THREAD_ID_ENV_VAR.to_string(), - context.session.conversation_id.to_string(), + context.session.thread_id.to_string(), ); let env = apply_unified_exec_env(env); let exec_server_env_config = ExecServerEnvConfig {