From 5fefa5e9dc2d10852d42473fdbf120535c55212f Mon Sep 17 00:00:00 2001 From: Roy Han Date: Tue, 24 Mar 2026 14:26:45 -0700 Subject: [PATCH] update schema --- codex-rs/core/src/analytics_client.rs | 100 +++++++++--------- codex-rs/core/src/analytics_client_tests.rs | 30 +++--- codex-rs/core/src/codex.rs | 71 +++++++------ codex-rs/core/src/codex_tests.rs | 1 + codex-rs/core/tests/common/test_codex.rs | 1 + codex-rs/core/tests/suite/apply_patch_cli.rs | 7 ++ codex-rs/core/tests/suite/approvals.rs | 1 + codex-rs/core/tests/suite/client.rs | 2 + codex-rs/core/tests/suite/code_mode.rs | 1 + .../tests/suite/collaboration_instructions.rs | 2 + codex-rs/core/tests/suite/compact.rs | 7 ++ codex-rs/core/tests/suite/exec_policy.rs | 2 + codex-rs/core/tests/suite/image_rollout.rs | 2 + codex-rs/core/tests/suite/items.rs | 18 +++- codex-rs/core/tests/suite/json_result.rs | 1 + codex-rs/core/tests/suite/live_reload.rs | 1 + codex-rs/core/tests/suite/model_switching.rs | 14 +++ .../core/tests/suite/model_visible_layout.rs | 5 + codex-rs/core/tests/suite/models_cache_ttl.rs | 1 + .../core/tests/suite/models_etag_responses.rs | 1 + codex-rs/core/tests/suite/personality.rs | 13 +++ codex-rs/core/tests/suite/prompt_caching.rs | 5 + codex-rs/core/tests/suite/remote_models.rs | 4 + .../core/tests/suite/request_permissions.rs | 1 + .../tests/suite/request_permissions_tool.rs | 1 + .../core/tests/suite/request_user_input.rs | 2 + codex-rs/core/tests/suite/rmcp_client.rs | 6 ++ .../tests/suite/safety_check_downgrade.rs | 4 + codex-rs/core/tests/suite/shell_snapshot.rs | 4 + codex-rs/core/tests/suite/skill_approval.rs | 1 + codex-rs/core/tests/suite/skills.rs | 1 + codex-rs/core/tests/suite/sqlite_state.rs | 1 + codex-rs/core/tests/suite/tool_harness.rs | 5 + codex-rs/core/tests/suite/tool_parallelism.rs | 2 + codex-rs/core/tests/suite/truncation.rs | 1 + codex-rs/core/tests/suite/unified_exec.rs | 26 +++++ codex-rs/core/tests/suite/user_shell_cmd.rs | 1 + codex-rs/core/tests/suite/view_image.rs | 14 +++ .../core/tests/suite/websocket_fallback.rs | 1 + codex-rs/tui/src/chatwidget.rs | 1 + 40 files changed, 259 insertions(+), 103 deletions(-) diff --git a/codex-rs/core/src/analytics_client.rs b/codex-rs/core/src/analytics_client.rs index 93510dfe93..86183d7c88 100644 --- a/codex-rs/core/src/analytics_client.rs +++ b/codex-rs/core/src/analytics_client.rs @@ -33,8 +33,8 @@ pub(crate) struct TrackEventsContext { } #[derive(Clone)] -pub(crate) struct TurnMetadata { - pub(crate) turn_type: Option, +pub(crate) struct CodexTurnEvent { + pub(crate) submission_origin: Option, pub(crate) model_provider: String, pub(crate) sandbox_policy: SandboxPolicy, pub(crate) reasoning_effort: Option, @@ -50,7 +50,7 @@ pub(crate) struct TurnMetadata { #[derive(Clone, Copy, Debug, Serialize)] #[serde(rename_all = "snake_case")] -pub(crate) enum TurnType { +pub(crate) enum SubmissionOrigin { Prompt, PromptQueued, } @@ -63,7 +63,7 @@ pub(crate) enum TurnEventType { } #[derive(Clone, Copy)] -pub(crate) struct UserMessageMetadata { +pub(crate) struct CodexTurnSteerEvent { pub(crate) user_message_type: UserMessageType, } @@ -128,8 +128,8 @@ impl AnalyticsEventsQueue { TrackEventsJob::AppUsed(job) => { send_track_app_used(&auth_manager, job).await; } - TrackEventsJob::TurnStart(job) => { - send_track_turn_start(&auth_manager, job).await; + TrackEventsJob::TurnEvent(job) => { + send_track_turn_event(&auth_manager, job).await; } TrackEventsJob::TurnSteer(job) => { send_track_turn_steer(&auth_manager, job).await; @@ -247,19 +247,23 @@ impl AnalyticsEventsClient { ); } - pub(crate) fn track_turn_start(&self, tracking: TrackEventsContext, turn_start: TurnMetadata) { - track_turn_start( + pub(crate) fn track_turn_event( + &self, + tracking: TrackEventsContext, + turn_event: CodexTurnEvent, + ) { + track_turn_event( &self.queue, Arc::clone(&self.config), Some(tracking), - turn_start, + turn_event, ); } pub(crate) fn track_turn_steer( &self, tracking: TrackEventsContext, - turn_steer: UserMessageMetadata, + turn_steer: CodexTurnSteerEvent, ) { track_turn_steer( &self.queue, @@ -310,7 +314,7 @@ enum TrackEventsJob { SkillInvocations(TrackSkillInvocationsJob), AppMentioned(TrackAppMentionedJob), AppUsed(TrackAppUsedJob), - TurnStart(TrackTurnStartJob), + TurnEvent(TrackTurnEventJob), TurnSteer(TrackTurnSteerJob), PluginUsed(TrackPluginUsedJob), PluginInstalled(TrackPluginManagementJob), @@ -337,16 +341,16 @@ struct TrackAppUsedJob { app: AppInvocation, } -struct TrackTurnStartJob { +struct TrackTurnEventJob { config: Arc, tracking: TrackEventsContext, - turn_start: TurnMetadata, + turn_event: CodexTurnEvent, } struct TrackTurnSteerJob { config: Arc, tracking: TrackEventsContext, - turn_steer: UserMessageMetadata, + turn_steer: CodexTurnSteerEvent, } struct TrackPluginUsedJob { @@ -433,13 +437,13 @@ struct CodexAppUsedEventRequest { } #[derive(Serialize)] -struct CodexTurnEvent { +struct CodexTurnEventParams { thread_id: Option, turn_id: Option, product_client_id: Option, model_slug: Option, turn_event_type: TurnEventType, - turn_type: Option, + submission_origin: Option, user_message_type: Option, model_provider: Option, sandbox_policy: Option<&'static str>, @@ -457,7 +461,7 @@ struct CodexTurnEvent { #[derive(Serialize)] struct CodexTurnEventRequest { event_type: &'static str, - event_params: CodexTurnEvent, + event_params: CodexTurnEventParams, } #[derive(Serialize)] @@ -561,11 +565,11 @@ pub(crate) fn track_app_used( queue.try_send(job); } -pub(crate) fn track_turn_start( +pub(crate) fn track_turn_event( queue: &AnalyticsEventsQueue, config: Arc, tracking: Option, - turn_start: TurnMetadata, + turn_event: CodexTurnEvent, ) { if config.analytics_enabled == Some(false) { return; @@ -573,10 +577,10 @@ pub(crate) fn track_turn_start( let Some(tracking) = tracking else { return; }; - let job = TrackEventsJob::TurnStart(TrackTurnStartJob { + let job = TrackEventsJob::TurnEvent(TrackTurnEventJob { config, tracking, - turn_start, + turn_event, }); queue.try_send(job); } @@ -585,7 +589,7 @@ pub(crate) fn track_turn_steer( queue: &AnalyticsEventsQueue, config: Arc, tracking: Option, - turn_steer: UserMessageMetadata, + turn_steer: CodexTurnSteerEvent, ) { if config.analytics_enabled == Some(false) { return; @@ -726,15 +730,15 @@ async fn send_track_app_used(auth_manager: &AuthManager, job: TrackAppUsedJob) { send_track_events(auth_manager, config, events).await; } -async fn send_track_turn_start(auth_manager: &AuthManager, job: TrackTurnStartJob) { - let TrackTurnStartJob { +async fn send_track_turn_event(auth_manager: &AuthManager, job: TrackTurnEventJob) { + let TrackTurnEventJob { config, tracking, - turn_start, + turn_event, } = job; let events = vec![TrackEventRequest::TurnEvent(CodexTurnEventRequest { event_type: "codex_turn_event", - event_params: codex_turn_start_event(&tracking, turn_start), + event_params: codex_turn_event_params(&tracking, turn_event), })]; send_track_events(auth_manager, config, events).await; @@ -748,7 +752,7 @@ async fn send_track_turn_steer(auth_manager: &AuthManager, job: TrackTurnSteerJo } = job; let events = vec![TrackEventRequest::TurnEvent(CodexTurnEventRequest { event_type: "codex_turn_event", - event_params: codex_turn_steer_event(&tracking, turn_steer), + event_params: codex_turn_steer_event_params(&tracking, turn_steer), })]; send_track_events(auth_manager, config, events).await; @@ -818,48 +822,48 @@ fn codex_app_metadata(tracking: &TrackEventsContext, app: AppInvocation) -> Code } } -fn codex_turn_start_event( +fn codex_turn_event_params( tracking: &TrackEventsContext, - turn_start: TurnMetadata, -) -> CodexTurnEvent { - CodexTurnEvent { + turn_event: CodexTurnEvent, +) -> CodexTurnEventParams { + CodexTurnEventParams { thread_id: Some(tracking.thread_id.clone()), turn_id: Some(tracking.turn_id.clone()), product_client_id: Some(crate::default_client::originator().value), model_slug: Some(tracking.model_slug.clone()), turn_event_type: TurnEventType::Start, - turn_type: turn_start.turn_type, + submission_origin: turn_event.submission_origin, user_message_type: None, - model_provider: Some(turn_start.model_provider), - sandbox_policy: Some(sandbox_policy_mode(&turn_start.sandbox_policy)), - reasoning_effort: turn_start.reasoning_effort.map(|value| value.to_string()), - reasoning_summary: reasoning_summary_mode(turn_start.reasoning_summary), + model_provider: Some(turn_event.model_provider), + sandbox_policy: Some(sandbox_policy_mode(&turn_event.sandbox_policy)), + reasoning_effort: turn_event.reasoning_effort.map(|value| value.to_string()), + reasoning_summary: reasoning_summary_mode(turn_event.reasoning_summary), service_tier: Some( - turn_start + turn_event .service_tier .map(|value| value.to_string()) .unwrap_or_else(|| "default".to_string()), ), - approval_policy: Some(turn_start.approval_policy.to_string()), - approvals_reviewer: Some(turn_start.approvals_reviewer.to_string()), - sandbox_network_access: Some(turn_start.sandbox_network_access), - collaboration_mode: Some(collaboration_mode_mode(turn_start.collaboration_mode)), - personality: personality_mode(turn_start.personality), - num_input_images: Some(turn_start.num_input_images), + approval_policy: Some(turn_event.approval_policy.to_string()), + approvals_reviewer: Some(turn_event.approvals_reviewer.to_string()), + sandbox_network_access: Some(turn_event.sandbox_network_access), + collaboration_mode: Some(collaboration_mode_mode(turn_event.collaboration_mode)), + personality: personality_mode(turn_event.personality), + num_input_images: Some(turn_event.num_input_images), } } -fn codex_turn_steer_event( +fn codex_turn_steer_event_params( tracking: &TrackEventsContext, - turn_steer: UserMessageMetadata, -) -> CodexTurnEvent { - CodexTurnEvent { + turn_steer: CodexTurnSteerEvent, +) -> CodexTurnEventParams { + CodexTurnEventParams { thread_id: Some(tracking.thread_id.clone()), turn_id: Some(tracking.turn_id.clone()), product_client_id: Some(crate::default_client::originator().value), model_slug: Some(tracking.model_slug.clone()), turn_event_type: TurnEventType::Steer, - turn_type: None, + submission_origin: None, user_message_type: Some(turn_steer.user_message_type), model_provider: None, sandbox_policy: None, diff --git a/codex-rs/core/src/analytics_client_tests.rs b/codex-rs/core/src/analytics_client_tests.rs index f31fcd21cd..54a804c71b 100644 --- a/codex-rs/core/src/analytics_client_tests.rs +++ b/codex-rs/core/src/analytics_client_tests.rs @@ -4,20 +4,20 @@ use super::CodexAppMentionedEventRequest; use super::CodexAppUsedEventRequest; use super::CodexPluginEventRequest; use super::CodexPluginUsedEventRequest; +use super::CodexTurnEvent; use super::CodexTurnEventRequest; +use super::CodexTurnSteerEvent; use super::InvocationType; +use super::SubmissionOrigin; use super::TrackEventRequest; use super::TrackEventsContext; use super::TurnEventType; -use super::TurnMetadata; -use super::TurnType; -use super::UserMessageMetadata; use super::UserMessageType; use super::codex_app_metadata; use super::codex_plugin_metadata; use super::codex_plugin_used_metadata; -use super::codex_turn_start_event; -use super::codex_turn_steer_event; +use super::codex_turn_event_params; +use super::codex_turn_steer_event_params; use super::normalize_path_for_skill_id; use crate::plugins::AppConnectorId; use crate::plugins::PluginCapabilitySummary; @@ -202,7 +202,7 @@ fn app_used_dedupe_is_keyed_by_turn_and_connector() { } #[test] -fn turn_start_event_serializes_expected_shape() { +fn turn_event_serializes_expected_shape() { let tracking = TrackEventsContext { model_slug: "gpt-5".to_string(), thread_id: "thread-2".to_string(), @@ -210,11 +210,11 @@ fn turn_start_event_serializes_expected_shape() { }; let event = TrackEventRequest::TurnEvent(CodexTurnEventRequest { event_type: "codex_turn_event", - event_params: codex_turn_start_event( + event_params: codex_turn_event_params( &tracking, - TurnMetadata { + CodexTurnEvent { + submission_origin: Some(SubmissionOrigin::Prompt), model_provider: "openai".to_string(), - turn_type: Some(TurnType::Prompt), sandbox_policy: SandboxPolicy::new_read_only_policy(), reasoning_effort: Some(ReasoningEffort::High), reasoning_summary: Some(ReasoningSummary::Detailed), @@ -229,7 +229,7 @@ fn turn_start_event_serializes_expected_shape() { ), }); - let payload = serde_json::to_value(&event).expect("serialize turn metadata event"); + let payload = serde_json::to_value(&event).expect("serialize codex turn event"); assert_eq!( payload, @@ -241,7 +241,7 @@ fn turn_start_event_serializes_expected_shape() { "product_client_id": crate::default_client::originator().value, "model_slug": "gpt-5", "turn_event_type": "start", - "turn_type": "prompt", + "submission_origin": "prompt", "user_message_type": null, "model_provider": "openai", "sandbox_policy": "read_only", @@ -268,15 +268,15 @@ fn turn_steer_event_serializes_expected_shape() { }; let event = TrackEventRequest::TurnEvent(CodexTurnEventRequest { event_type: "codex_turn_event", - event_params: codex_turn_steer_event( + event_params: codex_turn_steer_event_params( &tracking, - UserMessageMetadata { + CodexTurnSteerEvent { user_message_type: UserMessageType::PromptSteering, }, ), }); - let payload = serde_json::to_value(&event).expect("serialize input message metadata event"); + let payload = serde_json::to_value(&event).expect("serialize codex turn steer event"); assert_eq!( payload, @@ -288,7 +288,7 @@ fn turn_steer_event_serializes_expected_shape() { "product_client_id": crate::default_client::originator().value, "model_slug": "gpt-5", "turn_event_type": "steer", - "turn_type": null, + "submission_origin": null, "user_message_type": "prompt_steering", "sandbox_policy": null, "reasoning_effort": null, diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 9f107b4e9a..209c475102 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -14,10 +14,10 @@ use crate::agent::AgentStatus; use crate::agent::agent_status_from_event; use crate::analytics_client::AnalyticsEventsClient; use crate::analytics_client::AppInvocation; +use crate::analytics_client::CodexTurnEvent; +use crate::analytics_client::CodexTurnSteerEvent; use crate::analytics_client::InvocationType; -use crate::analytics_client::TurnMetadata; -use crate::analytics_client::TurnType; -use crate::analytics_client::UserMessageMetadata; +use crate::analytics_client::SubmissionOrigin; use crate::analytics_client::build_track_events_context; use crate::apps::render_apps_section; use crate::auth_env_telemetry::collect_auth_env_telemetry; @@ -3940,7 +3940,7 @@ impl Session { if let Some(tracking) = self.active_turn_tracking().await { self.services.analytics_events_client.track_turn_steer( tracking, - UserMessageMetadata { + CodexTurnSteerEvent { user_message_type: SubmittedUserMessageType::PromptSteering, }, ); @@ -5709,37 +5709,6 @@ pub(crate) async fn run_turn( .await; user_prompt_submit_outcome.additional_contexts }; - if !input.is_empty() { - let user_message_type = turn_context - .user_message_type - .unwrap_or(SubmittedUserMessageType::Prompt); - sess.services.analytics_events_client.track_turn_start( - tracking.clone(), - TurnMetadata { - model_provider: turn_context.config.model_provider_id.clone(), - turn_type: match user_message_type { - SubmittedUserMessageType::Prompt => Some(TurnType::Prompt), - SubmittedUserMessageType::PromptQueued => Some(TurnType::PromptQueued), - SubmittedUserMessageType::PromptSteering => None, - }, - sandbox_policy: turn_context.sandbox_policy.get().clone(), - reasoning_effort: turn_context.reasoning_effort, - reasoning_summary: Some(turn_context.reasoning_summary), - service_tier: turn_context.config.service_tier, - approval_policy: turn_context.approval_policy.value(), - approvals_reviewer: turn_context.config.approvals_reviewer, - sandbox_network_access: turn_context.network_sandbox_policy.is_enabled(), - collaboration_mode: turn_context.collaboration_mode.mode, - personality: turn_context.personality, - num_input_images: input - .iter() - .filter(|item| { - matches!(item, UserInput::Image { .. } | UserInput::LocalImage { .. }) - }) - .count(), - }, - ); - } sess.services .analytics_events_client .track_app_mentioned(tracking.clone(), mentioned_app_invocations); @@ -6053,6 +6022,38 @@ pub(crate) async fn run_turn( } } + if !input.is_empty() { + let user_message_type = turn_context + .user_message_type + .unwrap_or(SubmittedUserMessageType::Prompt); + sess.services.analytics_events_client.track_turn_event( + tracking, + CodexTurnEvent { + submission_origin: match user_message_type { + SubmittedUserMessageType::Prompt => Some(SubmissionOrigin::Prompt), + SubmittedUserMessageType::PromptQueued => Some(SubmissionOrigin::PromptQueued), + SubmittedUserMessageType::PromptSteering => None, + }, + model_provider: turn_context.config.model_provider_id.clone(), + sandbox_policy: turn_context.sandbox_policy.get().clone(), + reasoning_effort: turn_context.reasoning_effort, + reasoning_summary: turn_context.reasoning_summary, + service_tier: turn_context.config.service_tier, + approval_policy: turn_context.approval_policy.value(), + approvals_reviewer: turn_context.config.approvals_reviewer, + sandbox_network_access: turn_context.network_sandbox_policy.is_enabled(), + collaboration_mode: turn_context.collaboration_mode.mode, + personality: turn_context.personality, + num_input_images: input + .iter() + .filter(|item| { + matches!(item, UserInput::Image { .. } | UserInput::LocalImage { .. }) + }) + .count(), + }, + ); + } + last_agent_message } diff --git a/codex-rs/core/src/codex_tests.rs b/codex-rs/core/src/codex_tests.rs index 8846f0a643..7e6aedc521 100644 --- a/codex-rs/core/src/codex_tests.rs +++ b/codex-rs/core/src/codex_tests.rs @@ -3067,6 +3067,7 @@ async fn user_turn_updates_approvals_reviewer() { final_output_json_schema: None, collaboration_mode: None, personality: config.personality, + user_message_type: None, }, ) .await; diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index c61631e5bf..5af047ddd2 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -731,6 +731,7 @@ impl TestCodex { service_tier, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/apply_patch_cli.rs b/codex-rs/core/tests/suite/apply_patch_cli.rs index d0cefcb616..ce54a36921 100644 --- a/codex-rs/core/tests/suite/apply_patch_cli.rs +++ b/codex-rs/core/tests/suite/apply_patch_cli.rs @@ -318,6 +318,7 @@ async fn apply_patch_cli_move_without_content_change_has_no_turn_diff( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -928,6 +929,7 @@ async fn apply_patch_shell_command_heredoc_with_cd_emits_turn_diff() -> Result<( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1010,6 +1012,7 @@ async fn apply_patch_shell_command_failure_propagates_error_and_skips_diff() -> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1162,6 +1165,7 @@ async fn apply_patch_emits_turn_diff_event_with_unified_diff( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1227,6 +1231,7 @@ async fn apply_patch_turn_diff_for_rename_with_content_change( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1300,6 +1305,7 @@ async fn apply_patch_aggregates_diff_across_multiple_tool_calls() -> Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1373,6 +1379,7 @@ async fn apply_patch_aggregates_diff_preserves_success_after_failure() -> Result service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/approvals.rs b/codex-rs/core/tests/suite/approvals.rs index 6ec05bedc2..45aca4e673 100644 --- a/codex-rs/core/tests/suite/approvals.rs +++ b/codex-rs/core/tests/suite/approvals.rs @@ -566,6 +566,7 @@ async fn submit_turn( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 5da71f556b..1616fc10e2 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -1323,6 +1323,7 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re collaboration_mode: Some(collaboration_mode), final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; @@ -1437,6 +1438,7 @@ async fn user_turn_explicit_reasoning_summary_overrides_model_catalog_default() collaboration_mode: None, final_output_json_schema: None, personality: None, + user_message_type: None, }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index fa8229ecc3..2823afb997 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -2327,6 +2327,7 @@ text( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index 1517d9968c..339213c2ed 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -191,6 +191,7 @@ async fn collaboration_instructions_added_on_user_turn() -> Result<()> { collaboration_mode: Some(collaboration_mode), final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -307,6 +308,7 @@ async fn user_turn_overrides_collaboration_instructions_after_override() -> Resu collaboration_mode: Some(turn_mode), final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index a54d740111..763b67a987 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -1666,6 +1666,7 @@ async fn auto_compact_runs_after_resume_when_token_usage_is_over_limit() { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await .unwrap(); @@ -1757,6 +1758,7 @@ async fn pre_sampling_compact_runs_on_switch_to_smaller_context_model() { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await .expect("submit first user turn"); @@ -1782,6 +1784,7 @@ async fn pre_sampling_compact_runs_on_switch_to_smaller_context_model() { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await .expect("submit second user turn"); @@ -1893,6 +1896,7 @@ async fn pre_sampling_compact_runs_after_resume_and_switch_to_smaller_model() { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await .expect("submit pre-resume turn"); @@ -1942,6 +1946,7 @@ async fn pre_sampling_compact_runs_after_resume_and_switch_to_smaller_model() { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await .expect("submit resumed user turn"); @@ -3145,6 +3150,7 @@ async fn snapshot_request_shape_pre_turn_compaction_strips_incoming_model_switch service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await .expect("submit first user turn"); @@ -3170,6 +3176,7 @@ async fn snapshot_request_shape_pre_turn_compaction_strips_incoming_model_switch service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await .expect("submit second user turn"); diff --git a/codex-rs/core/tests/suite/exec_policy.rs b/codex-rs/core/tests/suite/exec_policy.rs index fb055c970f..bae7255d79 100644 --- a/codex-rs/core/tests/suite/exec_policy.rs +++ b/codex-rs/core/tests/suite/exec_policy.rs @@ -59,6 +59,7 @@ async fn submit_user_turn( service_tier: None, collaboration_mode, personality: None, + user_message_type: None, }) .await?; Ok(()) @@ -140,6 +141,7 @@ async fn execpolicy_blocks_shell_invocation() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/image_rollout.rs b/codex-rs/core/tests/suite/image_rollout.rs index 1526fe11a2..0020b9e329 100644 --- a/codex-rs/core/tests/suite/image_rollout.rs +++ b/codex-rs/core/tests/suite/image_rollout.rs @@ -130,6 +130,7 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -214,6 +215,7 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index aba5926a8e..3e3b1d360d 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -163,7 +163,7 @@ async fn user_message_item_is_emitted() -> anyhow::Result<()> { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn user_turn_tracks_turn_start_analytics() -> anyhow::Result<()> { +async fn user_turn_tracks_turn_event_analytics() -> anyhow::Result<()> { skip_if_no_network!(Ok(())); let server = start_mock_server().await; @@ -210,6 +210,7 @@ async fn user_turn_tracks_turn_start_analytics() -> anyhow::Result<()> { }, }), personality: None, + user_message_type: None, }) .await?; @@ -243,7 +244,7 @@ async fn user_turn_tracks_turn_start_analytics() -> anyhow::Result<()> { let event_params = &event["event_params"]; - assert_eq!(event_params["turn_type"], "prompt"); + assert_eq!(event_params["submission_origin"], "prompt"); assert_eq!(event_params["sandbox_policy"], "read_only"); assert_eq!( event_params["product_client_id"], @@ -273,7 +274,7 @@ async fn user_turn_tracks_turn_start_analytics() -> anyhow::Result<()> { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn user_turn_tracks_turn_start_prompt_type_analytics() -> anyhow::Result<()> { +async fn user_turn_tracks_turn_event_prompt_type_analytics() -> anyhow::Result<()> { skip_if_no_network!(Ok(())); let server = start_mock_server().await; @@ -320,6 +321,7 @@ async fn user_turn_tracks_turn_start_prompt_type_analytics() -> anyhow::Result<( }, }), personality: None, + user_message_type: None, }) .await?; @@ -327,12 +329,12 @@ async fn user_turn_tracks_turn_start_prompt_type_analytics() -> anyhow::Result<( let event = wait_for_analytics_event(&server, "codex_turn_event", |event| { event["event_params"]["turn_event_type"] == "start" - && event["event_params"]["turn_type"] == "prompt" + && event["event_params"]["submission_origin"] == "prompt" }) .await; let event_params = &event["event_params"]; - assert_eq!(event_params["turn_type"], "prompt"); + assert_eq!(event_params["submission_origin"], "prompt"); assert_eq!( event_params["product_client_id"], serde_json::json!(codex_core::default_client::originator().value) @@ -408,6 +410,7 @@ async fn user_turn_tracks_turn_steer_analytics() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -869,6 +872,7 @@ async fn plan_mode_emits_plan_item_from_proposed_plan_block() -> anyhow::Result< service_tier: None, collaboration_mode: Some(collaboration_mode), personality: None, + user_message_type: None, }) .await?; @@ -946,6 +950,7 @@ async fn plan_mode_strips_plan_from_agent_messages() -> anyhow::Result<()> { service_tier: None, collaboration_mode: Some(collaboration_mode), personality: None, + user_message_type: None, }) .await?; @@ -1055,6 +1060,7 @@ async fn plan_mode_streaming_citations_are_stripped_across_added_deltas_and_done service_tier: None, collaboration_mode: Some(collaboration_mode), personality: None, + user_message_type: None, }) .await?; @@ -1242,6 +1248,7 @@ async fn plan_mode_streaming_proposed_plan_tag_split_across_added_and_delta_is_p service_tier: None, collaboration_mode: Some(collaboration_mode), personality: None, + user_message_type: None, }) .await?; @@ -1356,6 +1363,7 @@ async fn plan_mode_handles_missing_plan_close_tag() -> anyhow::Result<()> { service_tier: None, collaboration_mode: Some(collaboration_mode), personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/json_result.rs b/codex-rs/core/tests/suite/json_result.rs index 3b6f3e3f9c..c3efc4bf6f 100644 --- a/codex-rs/core/tests/suite/json_result.rs +++ b/codex-rs/core/tests/suite/json_result.rs @@ -88,6 +88,7 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/live_reload.rs b/codex-rs/core/tests/suite/live_reload.rs index 663cf47488..135e292184 100644 --- a/codex-rs/core/tests/suite/live_reload.rs +++ b/codex-rs/core/tests/suite/live_reload.rs @@ -69,6 +69,7 @@ async fn submit_skill_turn(test: &TestCodex, skill_path: PathBuf, prompt: &str) service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index a7c5ceb0d2..b948231a2e 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -134,6 +134,7 @@ async fn model_change_appends_model_instructions_developer_message() -> Result<( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -171,6 +172,7 @@ async fn model_change_appends_model_instructions_developer_message() -> Result<( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -231,6 +233,7 @@ async fn model_and_personality_change_only_appends_model_instructions() -> Resul service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -268,6 +271,7 @@ async fn model_and_personality_change_only_appends_model_instructions() -> Resul service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -410,6 +414,7 @@ async fn model_change_from_image_to_text_strips_prior_image_content() -> Result< service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -431,6 +436,7 @@ async fn model_change_from_image_to_text_strips_prior_image_content() -> Result< service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -539,6 +545,7 @@ async fn generated_image_is_replayed_for_image_capable_models() -> Result<()> { summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -560,6 +567,7 @@ async fn generated_image_is_replayed_for_image_capable_models() -> Result<()> { summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -671,6 +679,7 @@ async fn model_change_from_generated_image_to_text_preserves_prior_generated_ima summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -692,6 +701,7 @@ async fn model_change_from_generated_image_to_text_preserves_prior_generated_ima summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -805,6 +815,7 @@ async fn thread_rollback_after_generated_image_drops_entire_image_turn_history() summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -834,6 +845,7 @@ async fn thread_rollback_after_generated_image_drops_entire_image_turn_history() summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -989,6 +1001,7 @@ async fn model_switch_to_smaller_model_updates_token_context_window() -> Result< service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1048,6 +1061,7 @@ async fn model_switch_to_smaller_model_updates_token_context_window() -> Result< service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 49f635432f..3794c36db7 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -129,6 +129,7 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |event| { @@ -153,6 +154,7 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { service_tier: None, collaboration_mode: None, personality: Some(Personality::Friendly), + user_message_type: None, }) .await?; wait_for_event(&test.codex, |event| { @@ -232,6 +234,7 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |event| { @@ -256,6 +259,7 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |event| { @@ -366,6 +370,7 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul service_tier: None, collaboration_mode: None, personality: Some(Personality::Friendly), + user_message_type: None, }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index 3d5904bd7a..e85da8e65d 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -104,6 +104,7 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/models_etag_responses.rs b/codex-rs/core/tests/suite/models_etag_responses.rs index 272c820caf..2af4ccec2b 100644 --- a/codex-rs/core/tests/suite/models_etag_responses.rs +++ b/codex-rs/core/tests/suite/models_etag_responses.rs @@ -110,6 +110,7 @@ async fn refresh_models_on_models_etag_mismatch_and_avoid_duplicate_models_fetch service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index ed4da07168..d1af8db9c1 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -111,6 +111,7 @@ async fn user_turn_personality_none_does_not_add_update_message() -> anyhow::Res service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -162,6 +163,7 @@ async fn config_personality_some_sets_instructions_template() -> anyhow::Result< service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -220,6 +222,7 @@ async fn config_personality_none_sends_no_personality() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -284,6 +287,7 @@ async fn default_personality_is_pragmatic_without_config_toml() -> anyhow::Resul service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -336,6 +340,7 @@ async fn user_turn_personality_some_adds_update_message() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -374,6 +379,7 @@ async fn user_turn_personality_some_adds_update_message() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -441,6 +447,7 @@ async fn user_turn_personality_same_value_does_not_add_update_message() -> anyho service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -479,6 +486,7 @@ async fn user_turn_personality_same_value_does_not_add_update_message() -> anyho service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -559,6 +567,7 @@ async fn user_turn_personality_skips_if_feature_disabled() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -597,6 +606,7 @@ async fn user_turn_personality_skips_if_feature_disabled() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -714,6 +724,7 @@ async fn remote_model_friendly_personality_instructions_with_feature() -> anyhow service_tier: None, collaboration_mode: None, personality: Some(Personality::Friendly), + user_message_type: None, }) .await?; @@ -833,6 +844,7 @@ async fn user_turn_personality_remote_model_template_includes_update_message() - service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -871,6 +883,7 @@ async fn user_turn_personality_remote_model_template_includes_update_message() - service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 9be83e6bb0..9a83f437b0 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -712,6 +712,7 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res collaboration_mode: None, final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -825,6 +826,7 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a collaboration_mode: None, final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -846,6 +848,7 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a collaboration_mode: None, final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -951,6 +954,7 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu collaboration_mode: None, final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -972,6 +976,7 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu collaboration_mode: None, final_output_json_schema: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index 83d911533d..8a2611a6da 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -181,6 +181,7 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -244,6 +245,7 @@ async fn namespaced_model_slug_uses_catalog_metadata_without_fallback_warning() service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -404,6 +406,7 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -623,6 +626,7 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/request_permissions.rs b/codex-rs/core/tests/suite/request_permissions.rs index 7c16599bf0..395ef0d952 100644 --- a/codex-rs/core/tests/suite/request_permissions.rs +++ b/codex-rs/core/tests/suite/request_permissions.rs @@ -201,6 +201,7 @@ async fn submit_turn( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/request_permissions_tool.rs b/codex-rs/core/tests/suite/request_permissions_tool.rs index 14506f4a41..545bdabf5b 100644 --- a/codex-rs/core/tests/suite/request_permissions_tool.rs +++ b/codex-rs/core/tests/suite/request_permissions_tool.rs @@ -153,6 +153,7 @@ async fn submit_turn( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/request_user_input.rs b/codex-rs/core/tests/suite/request_user_input.rs index 8e30b37c21..59f59500bd 100644 --- a/codex-rs/core/tests/suite/request_user_input.rs +++ b/codex-rs/core/tests/suite/request_user_input.rs @@ -153,6 +153,7 @@ async fn request_user_input_round_trip_for_mode(mode: ModeKind) -> anyhow::Resul }, }), personality: None, + user_message_type: None, }) .await?; @@ -264,6 +265,7 @@ where service_tier: None, collaboration_mode: Some(collaboration_mode), personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index 6cbf9521ba..d85b00bb88 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -137,6 +137,7 @@ async fn stdio_server_round_trip() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -307,6 +308,7 @@ async fn stdio_image_responses_round_trip() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -511,6 +513,7 @@ async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Re service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -626,6 +629,7 @@ async fn stdio_server_propagates_whitelisted_env_vars() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -788,6 +792,7 @@ async fn streamable_http_tool_call_round_trip() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1035,6 +1040,7 @@ async fn streamable_http_with_oauth_round_trip_impl() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/safety_check_downgrade.rs b/codex-rs/core/tests/suite/safety_check_downgrade.rs index 51a88ef16a..65fcc5b9e0 100644 --- a/codex-rs/core/tests/suite/safety_check_downgrade.rs +++ b/codex-rs/core/tests/suite/safety_check_downgrade.rs @@ -53,6 +53,7 @@ async fn openai_model_header_mismatch_emits_warning_event_and_warning_item() -> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -152,6 +153,7 @@ async fn response_model_field_mismatch_emits_warning_when_header_matches_request service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -238,6 +240,7 @@ async fn openai_model_header_mismatch_only_emits_one_warning_per_turn() -> Resul service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -288,6 +291,7 @@ async fn openai_model_header_casing_only_mismatch_does_not_warn() -> Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/shell_snapshot.rs b/codex-rs/core/tests/suite/shell_snapshot.rs index 0e044f3922..71b7497d61 100644 --- a/codex-rs/core/tests/suite/shell_snapshot.rs +++ b/codex-rs/core/tests/suite/shell_snapshot.rs @@ -172,6 +172,7 @@ async fn run_snapshot_command_with_options( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -263,6 +264,7 @@ async fn run_shell_command_snapshot_with_options( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -334,6 +336,7 @@ async fn run_tool_turn_on_harness( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -568,6 +571,7 @@ async fn shell_command_snapshot_still_intercepts_apply_patch() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/skill_approval.rs b/codex-rs/core/tests/suite/skill_approval.rs index 5a50e09cee..e34ee0d23c 100644 --- a/codex-rs/core/tests/suite/skill_approval.rs +++ b/codex-rs/core/tests/suite/skill_approval.rs @@ -73,6 +73,7 @@ async fn submit_turn_with_policies( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index 388618b56a..070ef0f40d 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -82,6 +82,7 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/sqlite_state.rs b/codex-rs/core/tests/suite/sqlite_state.rs index 2df92dbf95..29350c938f 100644 --- a/codex-rs/core/tests/suite/sqlite_state.rs +++ b/codex-rs/core/tests/suite/sqlite_state.rs @@ -403,6 +403,7 @@ async fn mcp_call_marks_thread_memory_mode_polluted_when_configured() -> Result< service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; wait_for_event(&test.codex, |event| { diff --git a/codex-rs/core/tests/suite/tool_harness.rs b/codex-rs/core/tests/suite/tool_harness.rs index 9594195a5b..978671d304 100644 --- a/codex-rs/core/tests/suite/tool_harness.rs +++ b/codex-rs/core/tests/suite/tool_harness.rs @@ -93,6 +93,7 @@ async fn shell_tool_executes_command_and_streams_output() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -164,6 +165,7 @@ async fn update_plan_tool_emits_plan_update_event() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -245,6 +247,7 @@ async fn update_plan_tool_rejects_malformed_payload() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -341,6 +344,7 @@ async fn apply_patch_tool_executes_and_emits_patch_events() -> anyhow::Result<() service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -445,6 +449,7 @@ async fn apply_patch_reports_parse_diagnostics() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/tool_parallelism.rs b/codex-rs/core/tests/suite/tool_parallelism.rs index faff0b2e09..37e2a1ca83 100644 --- a/codex-rs/core/tests/suite/tool_parallelism.rs +++ b/codex-rs/core/tests/suite/tool_parallelism.rs @@ -50,6 +50,7 @@ async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -367,6 +368,7 @@ async fn shell_tools_start_before_response_completed_when_stream_delayed() -> an service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/truncation.rs b/codex-rs/core/tests/suite/truncation.rs index f10567de24..3b47a952df 100644 --- a/codex-rs/core/tests/suite/truncation.rs +++ b/codex-rs/core/tests/suite/truncation.rs @@ -494,6 +494,7 @@ async fn mcp_image_output_preserves_image_and_no_text_summary() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/unified_exec.rs b/codex-rs/core/tests/suite/unified_exec.rs index c07fd20e5e..52b282ad8c 100644 --- a/codex-rs/core/tests/suite/unified_exec.rs +++ b/codex-rs/core/tests/suite/unified_exec.rs @@ -200,6 +200,7 @@ async fn unified_exec_intercepts_apply_patch_exec_command() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -334,6 +335,7 @@ async fn unified_exec_emits_exec_command_begin_event() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -417,6 +419,7 @@ async fn unified_exec_resolves_relative_workdir() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -503,6 +506,7 @@ async fn unified_exec_respects_workdir_override() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -601,6 +605,7 @@ async fn unified_exec_emits_exec_command_end_event() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -681,6 +686,7 @@ async fn unified_exec_emits_output_delta_for_exec_command() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -762,6 +768,7 @@ async fn unified_exec_full_lifecycle_with_background_end_event() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -897,6 +904,7 @@ async fn unified_exec_emits_terminal_interaction_for_write_stdin() -> Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1039,6 +1047,7 @@ async fn unified_exec_terminal_interaction_captures_delayed_output() -> Result<( service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1204,6 +1213,7 @@ async fn unified_exec_emits_one_begin_and_one_end_event() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1307,6 +1317,7 @@ async fn exec_command_reports_chunk_and_exit_metadata() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1430,6 +1441,7 @@ async fn unified_exec_defaults_to_pipe() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1525,6 +1537,7 @@ async fn unified_exec_can_enable_tty() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1611,6 +1624,7 @@ async fn unified_exec_respects_early_exit_notifications() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1747,6 +1761,7 @@ async fn write_stdin_returns_exit_metadata_and_clears_session() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1920,6 +1935,7 @@ async fn unified_exec_emits_end_event_when_session_dies_via_stdin() -> Result<() service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2002,6 +2018,7 @@ async fn unified_exec_keeps_long_running_session_after_turn_end() -> Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2095,6 +2112,7 @@ async fn unified_exec_interrupt_preserves_long_running_session() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2204,6 +2222,7 @@ async fn unified_exec_reuses_session_via_stdin() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2344,6 +2363,7 @@ PY service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; // This is a worst case scenario for the truncate logic. @@ -2463,6 +2483,7 @@ async fn unified_exec_timeout_and_followup_poll() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2564,6 +2585,7 @@ PY service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2665,6 +2687,7 @@ async fn unified_exec_runs_under_sandbox() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2774,6 +2797,7 @@ async fn unified_exec_python_prompt_under_seatbelt() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -2874,6 +2898,7 @@ async fn unified_exec_runs_on_all_platforms() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -3014,6 +3039,7 @@ async fn unified_exec_prunes_exited_sessions_first() -> Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/user_shell_cmd.rs b/codex-rs/core/tests/suite/user_shell_cmd.rs index 801ff76274..52f7314b30 100644 --- a/codex-rs/core/tests/suite/user_shell_cmd.rs +++ b/codex-rs/core/tests/suite/user_shell_cmd.rs @@ -184,6 +184,7 @@ async fn user_shell_command_does_not_replace_active_turn() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index 732d6b29eb..906cb33b75 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -178,6 +178,7 @@ async fn user_turn_with_local_image_attaches_image() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -287,6 +288,7 @@ async fn view_image_tool_attaches_local_image() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -428,6 +430,7 @@ async fn view_image_tool_can_preserve_original_resolution_when_requested_on_gpt5 summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -527,6 +530,7 @@ async fn view_image_tool_errors_clearly_for_unsupported_detail_values() -> anyho summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -619,6 +623,7 @@ async fn view_image_tool_treats_null_detail_as_omitted() -> anyhow::Result<()> { summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -719,6 +724,7 @@ async fn view_image_tool_resizes_when_model_lacks_original_detail_support() -> a summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -830,6 +836,7 @@ async fn view_image_tool_does_not_force_original_resolution_with_capability_feat summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -932,6 +939,7 @@ await codex.emitImage(out); service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1052,6 +1060,7 @@ console.log(out.type); summary: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1145,6 +1154,7 @@ async fn view_image_tool_errors_when_path_is_directory() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1221,6 +1231,7 @@ async fn view_image_tool_errors_for_non_image_files() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1302,6 +1313,7 @@ async fn view_image_tool_errors_when_file_missing() -> anyhow::Result<()> { service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1425,6 +1437,7 @@ async fn view_image_tool_returns_unsupported_message_for_text_only_model() -> an service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; @@ -1500,6 +1513,7 @@ async fn replaces_invalid_local_image_after_bad_request() -> anyhow::Result<()> service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/core/tests/suite/websocket_fallback.rs b/codex-rs/core/tests/suite/websocket_fallback.rs index e7f33df148..e9ec81f984 100644 --- a/codex-rs/core/tests/suite/websocket_fallback.rs +++ b/codex-rs/core/tests/suite/websocket_fallback.rs @@ -164,6 +164,7 @@ async fn websocket_fallback_hides_first_websocket_retry_stream_error() -> Result service_tier: None, collaboration_mode: None, personality: None, + user_message_type: None, }) .await?; diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 4c3c30e81c..ae33b1d95b 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -5279,6 +5279,7 @@ impl ChatWidget { final_output_json_schema: None, collaboration_mode, personality, + user_message_type: None, }; if !self.submit_op(op) {