update schema

This commit is contained in:
Roy Han
2026-03-24 14:26:45 -07:00
parent 1d4cee82bf
commit 1ab00f1609
40 changed files with 242 additions and 86 deletions
+46 -42
View File
@@ -30,8 +30,8 @@ pub(crate) struct TrackEventsContext {
}
#[derive(Clone)]
pub(crate) struct TurnMetadata {
pub(crate) turn_type: Option<TurnType>,
pub(crate) struct CodexTurnEvent {
pub(crate) submission_origin: Option<SubmissionOrigin>,
pub(crate) sandbox_policy: SandboxPolicy,
pub(crate) reasoning_effort: Option<ReasoningEffort>,
pub(crate) reasoning_summary: ReasoningSummary,
@@ -41,7 +41,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,
}
@@ -54,7 +54,7 @@ pub(crate) enum TurnEventType {
}
#[derive(Clone, Copy)]
pub(crate) struct UserMessageMetadata {
pub(crate) struct CodexTurnSteerEvent {
pub(crate) user_message_type: UserMessageType,
}
@@ -119,8 +119,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;
@@ -238,19 +238,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,
@@ -301,7 +305,7 @@ enum TrackEventsJob {
SkillInvocations(TrackSkillInvocationsJob),
AppMentioned(TrackAppMentionedJob),
AppUsed(TrackAppUsedJob),
TurnStart(TrackTurnStartJob),
TurnEvent(TrackTurnEventJob),
TurnSteer(TrackTurnSteerJob),
PluginUsed(TrackPluginUsedJob),
PluginInstalled(TrackPluginManagementJob),
@@ -328,16 +332,16 @@ struct TrackAppUsedJob {
app: AppInvocation,
}
struct TrackTurnStartJob {
struct TrackTurnEventJob {
config: Arc<Config>,
tracking: TrackEventsContext,
turn_start: TurnMetadata,
turn_event: CodexTurnEvent,
}
struct TrackTurnSteerJob {
config: Arc<Config>,
tracking: TrackEventsContext,
turn_steer: UserMessageMetadata,
turn_steer: CodexTurnSteerEvent,
}
struct TrackPluginUsedJob {
@@ -424,13 +428,13 @@ struct CodexAppUsedEventRequest {
}
#[derive(Serialize)]
struct CodexTurnEvent {
struct CodexTurnEventParams {
thread_id: Option<String>,
turn_id: Option<String>,
product_client_id: Option<String>,
model_slug: Option<String>,
turn_event_type: TurnEventType,
turn_type: Option<TurnType>,
submission_origin: Option<SubmissionOrigin>,
user_message_type: Option<UserMessageType>,
sandbox_policy: Option<&'static str>,
reasoning_effort: Option<String>,
@@ -442,7 +446,7 @@ struct CodexTurnEvent {
#[derive(Serialize)]
struct CodexTurnEventRequest {
event_type: &'static str,
event_params: CodexTurnEvent,
event_params: CodexTurnEventParams,
}
#[derive(Serialize)]
@@ -546,11 +550,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<Config>,
tracking: Option<TrackEventsContext>,
turn_start: TurnMetadata,
turn_event: CodexTurnEvent,
) {
if config.analytics_enabled == Some(false) {
return;
@@ -558,10 +562,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);
}
@@ -570,7 +574,7 @@ pub(crate) fn track_turn_steer(
queue: &AnalyticsEventsQueue,
config: Arc<Config>,
tracking: Option<TrackEventsContext>,
turn_steer: UserMessageMetadata,
turn_steer: CodexTurnSteerEvent,
) {
if config.analytics_enabled == Some(false) {
return;
@@ -711,15 +715,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;
@@ -733,7 +737,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;
@@ -803,37 +807,37 @@ 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,
sandbox_policy: Some(sandbox_policy_mode(&turn_start.sandbox_policy)),
reasoning_effort: turn_start.reasoning_effort.map(|value| value.to_string()),
reasoning_summary: Some(turn_start.reasoning_summary.to_string()),
service_tier: turn_start.service_tier.map(|value| value.to_string()),
collaboration_mode: Some(collaboration_mode_mode(turn_start.collaboration_mode)),
sandbox_policy: Some(sandbox_policy_mode(&turn_event.sandbox_policy)),
reasoning_effort: turn_event.reasoning_effort.map(|value| value.to_string()),
reasoning_summary: Some(turn_event.reasoning_summary.to_string()),
service_tier: turn_event.service_tier.map(|value| value.to_string()),
collaboration_mode: Some(collaboration_mode_mode(turn_event.collaboration_mode)),
}
}
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),
sandbox_policy: None,
reasoning_effort: None,
+15 -15
View File
@@ -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;
@@ -199,7 +199,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(),
@@ -207,10 +207,10 @@ 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 {
turn_type: Some(TurnType::Prompt),
CodexTurnEvent {
submission_origin: Some(SubmissionOrigin::Prompt),
sandbox_policy: SandboxPolicy::new_read_only_policy(),
reasoning_effort: Some(ReasoningEffort::High),
reasoning_summary: ReasoningSummary::Detailed,
@@ -220,7 +220,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,
@@ -232,7 +232,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,
"sandbox_policy": "read_only",
"reasoning_effort": "high",
@@ -253,15 +253,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,
@@ -273,7 +273,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,
+25 -24
View File
@@ -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,26 +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 {
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: turn_context.reasoning_summary,
service_tier: turn_context.config.service_tier,
collaboration_mode: turn_context.collaboration_mode.mode,
},
);
}
sess.services
.analytics_events_client
.track_app_mentioned(tracking.clone(), mentioned_app_invocations);
@@ -6042,6 +6022,27 @@ 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,
},
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,
collaboration_mode: turn_context.collaboration_mode.mode,
},
);
}
last_agent_message
}
+1
View File
@@ -3037,6 +3037,7 @@ async fn user_turn_updates_approvals_reviewer() {
final_output_json_schema: None,
collaboration_mode: None,
personality: config.personality,
user_message_type: None,
},
)
.await;